- 浏览: 29259 次
- 性别:
- 来自: 杭州
最新评论
-
mill2008:
翻译的很好,看了会英文的,实在有点晕,还是看这个比较快。不过貌 ...
Jmockit用户指南中文翻译(未校对)之三 -
az12xc34:
谢谢,我也想慢慢看懂,奈何英文水平有限,经理催的紧。没办法,
Jmockit用户指南中文翻译(未校对)之一 -
zhaoxuqi:
实力相当高,学习,嘿嘿
HttpSession框架 -
orcl_zhang:
恩,很好.
Ubuntu9.04 svn服务搭建
- 严格和非严格的期望
在期望块new Expectations(){...}中,默认所有被记录下来的期望都是严格的。这意味着,这些期望的调用必须在重播阶段被执行,而且需要按照声明的期 望指定的执行顺序执行,而且,也只允许这些调用被执行。任何一个没有被记录下来的非期望调用都会造成测试用例失败。
另一方面,当我们需要记录(录制)非严格(或者是松散)的期望时,那么我们可以使用mockit.NonStrictExpectations子 类。在一个非严格的期望块中,所有的被mock的类型的所有调用都可以在重播阶段执行,当然包括不在期望中声明的。也就是说,默认情况下,在重播阶段是否 执行mock类型的调用是不会造成测试用例失败的。同样,这种不严格的期望是不要求调用的执行顺序的。
缺省情况下,一个严格的期望会精确匹配重播阶段的一个调用。换而言之,这类型的期望是存在一个隐式的调用次数约束1,就好像它后面紧跟着 times=1这个约束。而另一方面,对于一个非严格的期望,默认是可以匹配重播阶段调用的任意次数的。它存在一个隐式的调用次数下限为0的约束,就好 像,被指定约束minTimes=0.然而,无论哪种情况,隐式的调用次数约束是可以被显式的约束(相当于使用times/minTimes /maxTimes 属性字段)覆盖的。所以,一个严格的期望也可以被设置成允许任何调用次数的约束,同样,非严格的期望约束也可以反过来(当然,其前提是我们确实需要这 样)。
请注意,对于一个严格的期望,所有在重播阶段被期望所匹配的调用,都会隐式被校验通过的。剩余的调用则被认为不符合期望(即造成测试失败),除非, 这个mock的类型被关联到一个非严格的期望上。所以,使用隐式验证的严格期望需要排除verification块的使用,这个块是用于调用的显式校验 的。实际上,在 new Verifications() {...}代码块中,只有那些匹配非严格期望的调用才被允许使用。同样,那些非严格的mock类型中的调用(没有被期望声明的)也可以显式记录。
为了允许在new Expectations(){...}代码块中混合使用严格和非严格调用,我们提供了一个mockit.NonStric注解用于mock属性域或者参 数。任何一个这样的mock类型都可以被认为是一个非严格期望,同时所有没有被录制的调用都可以运行在重播阶段执行(就是说,它们不被认为是非期望的执 行,因此不会造成测试失败)。这是特别有用的,以避免需要记录调用构造函数,或任何不感兴趣的方法。
在一个期望代码块中,一个独立的期望可以通过在调用语句后加上notStrict()方法将该期望标记为非严格期望,尽管在大多数情况下,使用non-strict期望块或者使用non-strict注解mock字段/参数会比这种方式更容易简单。
因此,对于给定一个测试,我们怎么在严格和非严格期望之间进行选择呢?这里没有普遍正确的答案。这通常会依赖于当前单元测试的特点以及个人的经验。总之,请谨记在脑袋的是,一个测试是可以同时混合使用这两种期望的,因此我们可以灵活的使用它们。
- Strict and non-strict mocks 严格和非严格mock
通常来说,我们最好站在一个独立的期望角度来思考使用严格性,而不是在一个mock实例或者类型上面考虑。等价的说法是,对于一个给定的mock实 例(或者类型)要么是严格的要么是非严格的。这意味着,特定实例/类型相关联的所有期望有相同的严格性。另一方面,在相同的测试,同时记录相同的mock 实例或类型的严格和非严格的期望,是完全有效的。而当使用在测试类级别声明的mock字段时,一个给定的mock实例在一个测试用例中是完全严格的,而同 时,在同一个测试类中,在另一个测试用例中,却是不严格的,这种情况是可以存在的。
总结下,我们可以指定三种不同严格性的方式:1)在一个给定的严格期望块中,如果需要指定某一个期望是非严格的,可以调用notStrict()方 法。2)对于一个特殊的mock类型/实例,其所有期望都需要是完全非严格的,则可以通过注解@NonStrict将其声明为一个mock属性字段或者参 数。3)如果在一个期望块中,需要所有的期望都是非严格的,则可以使用NonStrictExpectations类。
另一方面,这里没有提供任何一种方式去显式的指定某个给定的期望、mock类型/实例、或者一个完整的期望块应该是严格的。当我们没有指定期望是非 严格时,被记录下来的期望都被缺省认为是严格的。因此,对于一个期望需要被声明为严格时,它应该被记录在不在NonStrictExpectations 的期望expectation中,而对于mock类型,则不应该被注解为 @NonStrict. 而关联的mock类型和它相对应的所有实例都会被作为一个整体进行严格的校验,除了哪些匹配到一个被显式标记为非严格的调用。
最后,请注意,如果对于一个给定的Mock类型,在测试代码中没有任何相应的期望被记录,那么这个mock类型会自动被认为是一个完全不严格的(就好像这个mock的字段/参数被注解为 @NonStrict).
- Iterated expectations 迭代期望
当一系列有序连续的调用被记录在一个严格期望块中(调用之间的相对顺序与非严格的期望是无关的),整个序列则被期望在重播阶段执行。然而,让我们考虑下这 种情况,这些调用是在测试代码中的一个循环(或者任何其他迭代方式)里面执行。假设在测试代码中,我们是可以预先知道迭代次数,那么我们仍然记录这些期 望,匹配这些将在循环中执行的方法/构造函数(注意,我们并不是在一个期望代码块中,通过循环的方式声明调用期望)。通过使用 Expectations(int numberOfIterations)构造函数,下面的demo显示了这种特性。@Test public void recordStrictInvocationsInIteratingBlock(final Collaborator mock) { new Expectations(2) {{ mock.setSomething(anyInt); mock.save(); }}; // In the tested code: mock.setSomething(123); mock.save(); mock.setSomething(45); mock.save(); }
这种指定一组调用的迭代次数的方式也适用于非严格期望。然而,非严格期望的情况下,迭代次数只是用于指定调用次数的上限和下限限制约束(包括隐式和显式的)。所以,对于非严格期望来说,没有指定调用次数约束,是没有影响的。
- Explicit verification 显式验证(校验)
严格期望是隐式校验的,所以,不需要在一个显式的校验块重复校验。另一方面,非严格期望通常在一个校验结构块中通过显式的方式来校验mock类型的调用。就如不久将看到的一样,一个被录制下来的非严格期望仍然可以通过隐式方式来校验,而不需要在校验块中编码调用校验。
在new Verifications() {...}块中,我们可以使用和NonStrictExpectations() {...}同样的方法或者字段API,用于指定期望返回值以及异常错误。也就说,我们可以自由的使用anyXyz字段、 withXyz(...)方法来匹配方法参数,以及使用times、minTimes和maxTimes来指定调用次数的约束。请看下面的例子。
@Test public void verifyInvocationsExplicitlyAtEndOfTest(final Dependency mock) { // Nothing recorded here, but it could be. // Inside tested code: Dependency dependency = new Dependency(); dependency.doSomething(123, true, "abc-xyz"); // Verifies that Dependency#doSomething(int, boolean, String) was called at least once, // with arguments that obey the specified constraints: new Verifications() {{ mock.doSomething(anyInt, true, withPrefix("abc")); }};
注意,默认情况下,一个verification校验会检查是否在重播阶段至少存在一个调用匹配到该校验。当我们需要指定调用的准确次数(包括1),那么就需要指定times=n这个约束。
- Importing mocks from expectation blocks 从期望块中导入mock类型/实例
被声明在测试类属性字段域内的mock实例/类型,或者被声明在测试方法参数中的mock实例/类型,都是在校验块中使用。但是,我们知道,在 expectation块中同样可以声明一个局部的mock字段,这些字段是不可以被该块的外部使用。在这种情况下,我们可以参照下面的例子,将这些 mock实例导入到verification块中。
@Test public void importLocalMockFromPreviousNonStrictExpectationsBlock() { new NonStrictExpectations() { Dependency mock; { mock.notifyBeforeSave(); result = true; } }; // Inside tested code: Dependency dependency = new Dependency(); dependency.editABunchMoreStuff(); new Verifications() { Dependency mock; { mock.editABunchMoreStuff(); } }; }
这些被导入的mock类型是通过在verification中声明的字段域类型来标示的,而不是字段名称,尽管通常情况下,相同的字段名称可以用来避免冲突。当不需要mock参数时,或者在内部创建一个mock实例时,这种特性是很有用的(后面部分再作解释)。
- Verifying that an invocation never happened 判定一个调用从未执行
为此,可以在verification块内部,在一个不需要在重播阶段执行的调用期望语句后面,添加times = 0语句。如果存在一个或者多个匹配该声明的调用发生,则会造成测试用例失败。
- Verification in order 校验顺序
一般的verification块(就好像上面的那个),是无序的。实际就是说,对于aMethod()和 anotherMethod()方法在重播阶段的执行顺序是不要求校验的,只是,需要保证在重播阶段至少执行一次就行。如果你需要校验调用之间的执行顺 序,那么就可以使用new VerificationsInOrder() {...}来替代。 在这个代码块中,只需要简单的按照mock类型被执行的顺序编写就行了。@Test public void verifyingExpectationsInOrder(final DependencyAbc abc) { // Somewhere inside the tested code: abc.aMethod(); abc.doSomething("blah", 123); abc.anotherMethod(5); ... new VerificationsInOrder() {{ // The order of these invocations must be the same as the order // of occurrence during replay of the matching invocations. abc.aMethod(); abc.anotherMethod(anyInt); }}; }
注意到,abc.doSomething(...)方法是不需要校验的,所以,它可以在任何时间点被执行(或者根本就没执行)。
- Partially ordered verification 部分有序的校验
假设,你需要判定一个特殊的方法(构造函数)在其他调用之前/之后被执行,但是你又不关心其他调用的顺序,那么就可以简单的在合适的地方调用unverifiedInvocations()方法就可以到达这个目的了。下面demo显示了该用法。@Mocked DependencyAbc abc; @Mocked AnotherDependency xyz; @Test public void verifyingTheOrderOfSomeExpectationsRelativeToAllOthers() { new UnitUnderTest().doSomething(); new VerificationsInOrder() {{ abc.methodThatNeedsToExecuteFirst(); unverifiedInvocations(); // Invocations not verified must come here... xyz.method1(); abc.method2(); unverifiedInvocations(); // ... and/or here. xyz.methodThatNeedsToExecuteLast(); }}; }
上面的例子实际上有点复杂了,因为它校验挺多东西的:a)一个方法必须要在其他方法之前被调用执行;b)一个方法必须在其他方法之后被执 行;c)AnotherDependency#method1()必须在DependencyAbc#method2()执行之后被调用。在大多数的测试 代码中,我们只需要保证这几种不同顺序的一个调用顺序就可以了。但是,强大的地方就在于这里,我们可以很容易的使用多种复杂顺序校验。
另一种情景没有被上面例子覆盖到的是,我们需要判定一些调用按照给定的顺序执行,同时需要另一些调用按照任意顺序执行。对此,我们需要编写两个独立的verification校验块,就好像上面示例一样(这里的mock是一个测试类的mock属性字段)
@Test public void verifyFirstAndLastCallsWithOthersInBetweenInAnyOrder() { // Invocations that occur while exercising the code under test: mock.prepare(); mock.setSomethingElse("anotherValue"); mock.setSomething(123); mock.notifyBeforeSave(); mock.save(); new VerificationsInOrder() {{ mock.prepare(); // first expected call unverifiedInvocations(); // others at this point mock.notifyBeforeSave(); // just before last mock.save(); times = 1; // last expected call }}; // Unordered verification of the invocations previously left unverified. // Could be ordered, but then it would be simpler to just include these invocations // in the previous block, in the place of the "unverifiedInvocations()". new Verifications() {{ mock.setSomething(123); mock.setSomethingElse(anyString); }}; }
通常情况下,当在测试代码中存在多个verification校验块时,它们的执行顺序就很重要。
In the previous test, for example, if the unordered block came before it
would have left no "unverified invocations" to match a later call to
unverifiedInvocations(); the test would still pass (assuming it
originally passed) since it's not required that unverified invocations
actually occurred at the called position, but it would not have verified
that the unordered group of invocations occurred between the first and
last expected calls.
- Full verification 完整校验
有时候,对mock类型所有的调用进行校验可能是很重要的。这自然就是记录严格期望时的情况,因为任何一个不希望发生的调用被执行都会造成测试失败。当在 非严格期望中使用显式的校验时,可以使用new FullVerifications() {...}块来确保没有调用未被校验。@Test public void verifyAllInvocations(final Dependency mock) { // Code under test included here for easy reference: mock.setSomething(123); mock.setSomethingElse("anotherValue"); mock.setSomething(45); mock.save(); new FullVerifications() {{ // Verifications here are unordered, so the following invocations could be in any order. mock.setSomething(anyInt); // verifies two actual invocations mock.setSomethingElse(anyString); mock.save(); // if this verification (or any other above) is removed the test will fail }}; }
注意:如果一个下限约束(一个最小调用次数约束)被指定(除非是非严格期望),那么这个约束总会在测试代码最后结束前被隐式校验。因此,在全部验证块中显式的校验严格期望是没有必要的。
- Full verification in order有序的完整校验
目前,我们已经知道怎样使用Verifications处理无序的校验,如何使用VerificationsInOrder处理有序的校验,以及使用FullVerifications进行完整校验。但是,又如何处理有序的完整校验呢?足够的简单,如下:@Test public void verifyAllInvocationsInOrder(final Dependency mock) { // Code under test included here for easy reference: mock.setSomething(123); mock.setSomethingElse("anotherValue"); mock.setSomething(45); mock.save(); new FullVerificationsInOrder() {{ mock.setSomething(anyInt); mock.setSomethingElse(anyString); mock.setSomething(anyInt); mock.save(); }}; }
注意到,这里并没有什么不同的语法。在上面例子的verifyAllInvocations测试中,我们可以使用单一的verification校 验调用匹配两个独立mock.setSomething(...)方法。但是,在verifyAllInvocationsInOrder测试代码中,我 们在校验块中写了两个独立的调用,用来正确匹配。
现在,你可以会想,编写一个FullVerificationsInOrder其实就和编写一个Expectations块是一样的,因为 Expectations块中的所有期望都是严格的。那么我们是不是在重复造轮?并不完全是的。对于一个非严格的期望,缺省的被加上调用次数 minTimes = 1的约束,从而允许同一个方法或者构造函数在重播阶段可以多次执行。所以,在上面的例子中,如果setSomethingElse(...)方法在重播阶 段被连续二次调用执行,测试用例依然是可以通过的(前提是,第二次的调用需要按照期望顺序执行)。
- Restricting the set of mocked types to be fully verified (完全校验某些mock类型的特定集合)
默认情况下,对于给定的测试,当使用 new FullVerifications() {}或者new FullVerificationsInOrder() {} 结构块时,所有mock实例/类型的所有调用都必须显式校验。现在,如果我们有一个测试,它有两个(或者更多)mock类型,但是我们只需要对这些 mock类型中的某一个(如果是多于2个mock类型,则可能是一个mock子集)做完整的调用校验,该怎么办?答案就是,使用 FullVerifications(Object... mockedTypesAndInstancesToVerify)构造函数,它只对这些给出的mock类型实例进行完整校验。下面的测试代码提供这样的 例子。
@Test public void verifyAllInvocationsToOnlyOneOfTwoMockedTypes(Dependency mock1, AnotherDependency mock2) { // Inside code under test: mock1.prepare(); mock1.setSomething(123); mock2.doSomething(); mock1.editABunchMoreStuff(); mock1.save(); new FullVerifications(mock1) {{ mock1.prepare(); mock1.setSomething(anyInt); mock1.editABunchMoreStuff(); mock1.save(); times = 1; }}; }
在上面的测试中,mock2.doSomething()调用是不会被验证的。如果需要只是针对某个class的方法(也包括构造函数)需要校验, 这也是可能的,只是需要将class传递给FullVerifications(...)或者 FullVerificationsInOrder(...) 构造函数里面。例如,new FullVerificationsInOrder(AnotherDependency.class) { ... }这个验证块仅仅保证所有AnotherDependency class的mock类型才被校验。
- Verifying that no invocations occurred 验证没有任何调用被执行
为了在测试代码中验证非严格的mock类型/实例上的所有调用都没有执行,只需要添加一个空的完整校验块就行。一如往常,请注意,一个具有 times/minTimes调用次数约束的已记录的任何期望都会被隐式验证,因此不需要完整校验块;在这种情况下空校验块会确保没有其他调用发生。此 外,在同一个测试用例中,如果一个期望被之前的一个verification校验块验证过,则它同样不会被完整校验块所验证。
如果测试中使用了两个或者多个mock类型/实例,而你又需要校验某些Mock是没有任何调用发生的,那么就需要在一个空的校验块中指定需要校验的mock类型或者实例。正如下面例子所示:
@Test public void verifyNoInvocationsOnOneOfTwoMockedDependenciesBeyondThoseRecordedAsExpected( final Dependency mock1, final AnotherDependency mock2) { new NonStrictExpectations() {{ // These two are recorded as expected: mock1.setSomething(anyInt); minTimes = 1; mock2.doSomething(); times = 1; }}; // Inside code under test: mock1.prepare(); mock1.setSomething(1); mock1.setSomething(2); mock1.save(); mock2.doSomething(); // Will verify that no invocations other than to "doSomething()" occurred on mock2: new FullVerifications(mock2) {}; }
- Verifying unspecified invocations that should not happen 验证未指定的不应该发生的调用
一个完全校验块(无论是否有序)同样可以让我们来验证,某特定的方法和/或构造函数永远不会被调用,而无需为每一个方法/构造函数指定 times= 0。下面的测试提供了一个例子。@Test public void readOnlyOperation(final Dependency mock) { new NonStrictExpectations() {{ mock.getData(); result = "test data"; }}; // Code under test: String data = mock.getData(); // mock.save() should not be called here ... new FullVerifications() {{ mock.getData(); minTimes = 0; // calls to getData are allowed }}; }
如果在重播阶段,Dependency类的任何方法或者构造函数被调用,那么上面的测试将会失败,除非那些在校验块中显式的被校验 (Dependency#getData()就是这样)。另一方面,对于这种情况,我们根本不需要使用任何的验证块,而是更简单的使用一个严格期望就行 了。
- Verifying iterations 验证迭代
关于验证块,我们还有最后一种情况需要测试下:能够方便地验证发生在循环中的调用的循环迭代次数。@Test public void verifyAllInvocations(final Dependency mock) { int numberOfIterations = 3; // Code under test included here for easy reference: for (int i = 0; i < numberOfIterations; i++) { DataItem data = getData(i); mock.setData(data); mock.save(); } new Verifications(numberOfIterations) {{ mock.setData((DataItem) withNotNull()); mock.save(); }}; new VerificationsInOrder(numberOfIterations) {{ mock.setData((DataItem) withNotNull()); mock.save(); }}; }
上面使用两个verification验证块目的是用来解释有序和无序的迭代验证的区别。在第一个验证块中,每一个验证调用都必须至少重播阶段中相 同方法3次,因为迭代次数被传递到构造函数里。对于无序的迭代块,指定迭代次数会用来乘以下限和上限的调用次数,当在验证块内指定一个明确的约束,如一个 minTimes= 1; maxTimes= 4,就会被乘以迭代次数;在上面的例子中就相当于被各自被乘以3,转化成minTimes= 3; maxTimes= 12;.另一方面,在第二个验证块中,调用次数的约束则无效。相反,产生的效果相当于"展开循环",就好像验证块校验调用的重复每个迭代。
迭代的FullVerifications块的语义和正常的校验块是一样的。迭代FullVerificationsInOrder块和一个VerificationsInOrder块也是一样。
相关推荐
本次介绍的是ZEMAX的中文用户指南,该指南针对2008英文版进行了修订和更新,力图解决以往版本中诸如术语翻译不统一、内容缺失、排版不规范以及语句翻译不流畅等问题,以提升用户体验。 ZEMAX光学设计程序的用户指南...
入门指南部分会引导用户通过基础实例熟悉JaamSim,通过实际操作学习如何启动控制台、创建和运行仿真模型。JaamSim的安装过程非常简单,只需将可执行文件复制到所需目录,双击即可运行。TLS等特定应用程序的安装与...
java平台的API规范,标准版翻译校对版本,这是好心人翻译的,我认为目前是最好的中文api,分享下信息,chm版本
- **翻译历程**: 自2009年起,OWASP测试指南中文版经历了多次翻译和修订。最初由Frank Aaron等人启动翻译项目,后续有多位志愿者参与了翻译和校对工作。 - **中文版贡献者**: 包括程琼、Frank Fan、贺佳琳等在内的多...
**Z-stack开发指南-中文翻译-未纠错** Z-stack是由美国德州仪器(TI)提供的一种专为ZigBee无线网络设计的协议栈。ZigBee是一种基于IEEE 802.15.4标准的低功耗、低数据速率、近距离无线通信技术,广泛应用于智能...
本篇论文主要围绕着基于深度学习的中文文本自动校对展开研究与实现,针对中文文本的语法错误校对,利用深度学习模型进行自动化的文本纠错,旨在提高文本处理的效率和准确性。 一、研究背景与意义 随着互联网的快速...
在建筑工程领域,尤其是在结构设计阶段,准确的梁截面校对是至关重要的。"梁截面校对_梁截面校对_梁截面_cad_截面校对vlx_"这一标题暗示了我们讨论的主题是一款针对CAD软件的专用插件,用于辅助设计师进行梁截面的...
这份"Spring官方文档(中文翻译&人工校对)"是一份宝贵的资源,它帮助开发者准确理解Spring框架的核心概念和功能,无论你是初学者还是经验丰富的开发者,都能从中受益。 文档首先会介绍Spring的基本架构,包括其...
黑马校对软件百度网盘下载地址,精确校对领导人姓名、职务和领导人排序错误。 精确校对涉及台湾和其他敏感的政治性错误。 即时更新的、可自定义的领导人职务库。校对插件 直接嵌入在Acrobat中校对PDF文件。可把校对...
译者通过个人努力将英文指南翻译成中文,目的是为了推广和分享这个实用的内核,尽管自身并未决定在自己的系统中使用它。 翻译者的初衷是希望利用业余时间,边阅读边翻译,最终完成中文版文档。由于译者个人时间有限...
《校对能手》是一款中文文稿校对软件。可以快速对中文文档资料进行校对,检查出可能存在的差错,列出勘误表,供改稿时参考。同时,还有姓名筛查、人名地名索引自动编排、多能字词典、中文排序等功能。特别适用于快速...
《编辑助手》又名“校对能手”是一款中文文稿校对软件。在各种文稿的起草、修改、抄写、打字、排版过程中,难免出现各种差错,手工校对检查费时费力,往往还会有所遗漏。本软件针对上述问题,可以快速对中文文档资料...
中文文本自动校对系统的诞生,源于对大规模文本处理需求的增长,如新闻编辑、文档校对、机器翻译等领域。传统的手动校对方式效率低下,容易出错,而自动化校对则能显著提高效率,减少人为错误。 二、理论基础 1. ...
内含S2版、PS版、Word版、WPS版、小样版、飞腾插件版和PDF插件版等9个全新的校对界面,采用超大规模词库和重点词监控等先进的校对计算技术,在校对质量、校对功能和易用性等方面都有了飞跃性的提高,达到了当前电脑...
#### 三、高级校对技巧 - **上下文理解**:校对者需要具备良好的阅读理解和语言能力,以便能够准确判断文档中的逻辑是否连贯、语法是否正确。 - **一致性检查**:确保文档中术语、格式等方面的统一性。例如,在整个...
- **感谢词**:表达对参与翻译和校对工作的人员的感激之情。 综上所述,《LUA编程指南中文版》不仅是一本关于Lua语言的入门教材,更是深入探讨Lua特性和高级主题的宝贵资源。对于希望掌握这一强大而灵活的脚本语言...
哈萨克文字校对软件是一款专为哈萨克语用户设计的专业工具,旨在帮助哈萨克文字编辑者提升文本质量,确保拼写、语法和排版的准确性。这款软件结合了现代技术与哈萨克语的特性,为用户提供了一种高效、精准的校对解决...