之前介绍了如何设置mock对象预期调用的方法及返回值。下面介绍方法调用的验证,而它关注点则在mock对象的交互行为上,比如验证mock对象的某个方法调用参数,调用次数,顺序等等。下面来看例子:
@Test
public void verifyTestTest() {
List<String> mock = mock(List.class);
List<String> mock2 = mock(List.class);
when(mock.get(0)).thenReturn("hello");
mock.get(0);
mock.get(1);
mock.get(2);
mock2.get(0);
verify(mock).get(2);
verify(mock, never()).get(3);
verifyNoMoreInteractions(mock);
verifyZeroInteractions(mock2);
}
验证的基本方法
我们已经熟悉了使用verify(mock).someMethod(…)来验证方法的调用。例子中,我们mock了List接口,然后调用了mock对象的一些方法。验证是否调用了mock.get(2)方法可以通过verify(mock).get(2)来进行。verify方法的调用不关心是否模拟了get(2)方法的返回值,只关心mock对象后,是否执行了mock.get(2),如果没有执行,测试方法将不会通过。
验证未曾执行的方法
在verify方法中可以传入never()方法参数来确认mock.get(3)方法不曾被执行过。另外还有很多调用次数相关的参数将会在下面提到。
查询多余的方法调用
verifyNoMoreInteractions()方法可以传入多个mock对象作为参数,用来验证传入的这些mock对象是否存在没有验证过的调用方法。本例中传入参数mock,测试将不会通过,因为我们只verify了mock对象的get(2)方法,没有对get(0)和get(1)进行验证。为了增加测试的可维护性,官方不推荐我们过于频繁的在每个测试方法中都使用它,因为它只是测试的一个工具,只在你认为有必要的时候才用。
查询没有交互的mock对象
verifyZeroInteractions()也是一个测试工具,源码和verifyNoMoreInteractions()的实现是一样的,为了提高逻辑的可读性,所以只不过名字不同。在例子中,它的目的是用来确认mock2对象没有进行任何交互,但mock2执行了get(0)方法,所以这里测试会报错。由于它和verifyNoMoreInteractions()方法实现的源码都一样,因此如果在verifyZeroInteractions(mock2)执行之前对mock.get(0)进行了验证那么测试将会通过。
验证方法调用的次数
如果要验证Mock对象的某个方法调用次数,则需给verify方法传入相关的验证参数,它的调用接口是verify(T mock, VerificationMode mode)。如:verify(mock,times(3)).someMethod(argument)验证mock对象someMethod(argument)方法是否调用了三次。times(N)参数便是验证调用次数的参数,N代表方法调用次数。其实verify方法中如果不传调用次数的验证参数,它默认传入的便是times(1),即验证mock对象的方法是否只被调用一次,如果有多次调用测试方法将会失败。
Mockito除了提供times(N)方法供我们调用外,还提供了很多可选的方法:
never() 没有被调用,相当于times(0)
atLeast(N) 至少被调用N次
atLeastOnce() 相当于atLeast(1)
atMost(N) 最多被调用N次
超时验证
Mockito提供对超时的验证,但是目前不支持在下面提到的顺序验证中使用。进行超时验证和上述的次数验证一样,也要在verify中进行参数的传入,参数为timeout(int millis),timeout方法中输入的是毫秒值。下面看例子:
验证someMethod()是否能在指定的100毫秒中执行完毕
verify(mock, timeout(100)).someMethod();
结果和上面的例子一样,在超时验证的同时可进行调用次数验证,默认次数为1
verify(mock, timeout(100).times(1)).someMethod();
在给定的时间内完成执行次数
verify(mock, timeout(100).times(2)).someMethod();
给定的时间内至少执行两次
verify(mock, timeout(100).atLeast(2)).someMethod();
另外timeout也支持自定义的验证模式,
verify(mock, new Timeout(100, yourOwnVerificationMode)).someMethod();
验证方法调用的顺序
Mockito同样支持对不同Mock对象不同方法的调用次序进行验证。进行次序验证是,我们需要创建InOrder对象来进行支持。例:
创建mock对象
List<String> firstMock = mock(List.class);
List<String> secondMock = mock(List.class);
调用mock对象方法
firstMock.add("was called first");
firstMock.add("was called first");
secondMock.add("was called second");
secondMock.add("was called third");
创建InOrder对象
inOrder方法可以传入多个mock对象作为参数,这样便可对这些mock对象的方法进行调用顺序的验证InOrder inOrder = inOrder( secondMock, firstMock );
验证方法调用
接下来我们要调用InOrder对象的verify方法对mock方法的调用顺序进行验证。注意,这里必须是你对调用顺序的预期。
InOrder对象的verify方法也支持调用次数验证,上例中,我们期望firstMock.add("was called first")方法先执行并执行两次,所以进行了下面的验证inOrder.verify(firstMock,times(2)).add("was called first")。其次执行了secondMock.add("was called second")方法,继续验证此方法的执行inOrder.verify(secondMock).add("was called second")。如果mock方法的调用顺序和InOrder中verify的顺序不同,那么测试将执行失败。
InOrder的verifyNoMoreInteractions()方法
它用于确认上一个顺序验证方法之后,mock对象是否还有多余的交互。它和Mockito提供的静态方法verifyNoMoreInteractions不同,InOrder的验证是基于顺序的,另外它只验证创建它时所提供的mock对象,在本例中只对firstMock和secondMock有效。例如:
inOrder.verify(secondMock).add("was called second");
inOrder.verifyNoMoreInteractions();
在验证secondMock.add("was called second")方法之后,加上InOrder的verifyNoMoreInteractions方法,表示此方法调用后再没有多余的交互。例子中会报错,因为在此方法之后还执行了secondMock.add("was called third")。现在将上例改成:
inOrder.verify(secondMock).add("was called third");
inOrder.verifyNoMoreInteractions();
测试会恢复为正常,因为在secondMock.add("was called third")之后已经没有多余的方法调用了。如果这里换成Mockito类的verifyNoMoreInteractions方法测试还是会报错,它查找的是mock对象中是否存在没有验证的调用方法,和顺序是无关的。
分享到:
相关推荐
Mockito 是一个流行的Java单元测试框架,用于模拟对象行为,使得测试更为简洁和可控。JUnit则是最常用的Java单元测试库,它提供了一种结构化的方式来编写和运行测试用例。当我们进行单元测试时,Mockito 和 JUnit ...
2. **Stubbing**:这是定义mock对象行为的过程。你可以指定当特定的方法被调用时,mock对象应该如何响应。例如,你可以设置mock对象在某个方法被调用时返回特定的值。 3. **Verification**:Mockito提供了一种验证...
- 使用 Mockito 来模拟依赖对象,并编写测试用例来验证类的行为。 4. **添加行为:** - 使用 `when()` 方法来设置模拟对象的行为。 - 示例:`when(mockObject.methodName()).thenReturn(value);` 5. **验证行为...
2. **配置mock行为**:使用`whenever`关键字和lambda表达式来定义mock对象的行为,如`whenever(myMock.someMethod()).thenReturn(someValue)`。 3. **验证方法调用**:使用`verify`函数来检查方法是否被正确调用,如...
为了有效地利用“mockito-1.8.5.jar”,开发者需要将其添加到项目的类路径中,然后使用Mockito提供的API来创建mock对象,设置期望行为,并进行验证。同时,理解如何将Mockito与其他测试框架集成也是关键,这可能涉及...
1. **Mock对象创建**:Mockito可以轻松地创建mock对象,模拟对象的行为,而不涉及实际的实现。 2. **验证方法调用**:Mockito的`verify()`方法用于检查特定方法是否按预期被调用,以及调用次数和参数。 3. ** ...
4. 使用Mockito的API创建mock对象并设置期望行为。 5. 使用PowerMock的API模拟静态方法、final类或方法等。 6. 编写测试方法,调用要测试的代码,并使用Mockito验证方法调用是否符合预期。 通过以上步骤,开发者...
PowerMock 是一个扩展了其他Mock框架(如Mockito)的库,它允许开发者模拟那些通常无法被模拟的行为。在某些场景下,例如当你的代码依赖于静态方法或静态初始化块时,PowerMock 可以帮助你创建隔离的测试环境,以便...
在Python中使用Mockito时,开发者通常会在测试代码中导入mockito库,然后使用`mock`、`patch`等函数来创建和配置模拟对象。例如,如果有一个函数`foo`依赖于外部服务`bar`,可以使用Mockito创建`bar`的模拟对象,...
1. 模拟对象(Mock Object):模拟对象是真实对象的替代品,它可以预定义行为和返回值,以便在测试中控制依赖对象的行为。 2. 验证(Verification):验证是检查模拟对象在测试期间是否按照预期执行了某些操作,如...
Mockito 还提供了验证功能,可以检查 mock 对象的方法是否按预期被调用了。例如,`verify(mockObject).someMethod()` 会确保 `someMethod()` 被调用了一次。 5. **Stubbing( stubs)**: Stubbing 是指预先定义...
通过学习这个示例,开发者可以了解如何在实际项目中使用 Mockito 和 JUnit 进行单元测试,包括如何创建模拟对象、预定义行为、验证方法调用等。这对于提高代码质量、确保功能正确性至关重要,特别是在大型复杂项目中...
在Android测试中,Mockito允许我们创建“mock”对象,即代替真实对象的替身,这些mock对象可以在测试中替代真实的依赖,避免了实际调用其他组件可能带来的复杂性。例如,我们可以通过`@Mock`注解创建mock对象,然后...
Espresso 是 Google 推出的用于 Android 应用程序的 UI 测试工具,而 Mockito 是一个流行的 Java 单元测试框架,它允许开发者模拟对象行为以便于测试。 **Espresso** 是一个强大的 Android 测试框架,主要用于编写...
Mockito 还提供了许多高级特性,如 spy 对象(部分模拟对象)、argument matchers(匹配器)以及验证方法调用的顺序等。这些功能可以帮助我们编写更复杂的测试场景。 ### 10. 结论 通过结合 Mockito 和 JUnit,...
Mockito是一个流行的Java单元测试框架,它允许我们创建和配置模拟对象,以便在测试中隔离我们想要验证的代码部分。结合Spring Boot,我们可以确保我们的应用程序组件在独立环境中运行,不受其他依赖的影响。 首先,...
Mock对象完全不执行实际的方法,而是记录调用历史;而Spy对象则是在真实对象的基础上创建的,它会执行实际的方法,但允许你为某些特定行为设置模拟。 在Mockito中,你可以使用`when()`方法来定义模拟对象的预期行为...
Mockito提供了一种简洁的API,通过`mock()`方法创建模拟对象,通过`when()`定义模拟对象的行为,通过`verify()`检查模拟对象的方法是否被正确调用。例如: ```java // 创建模拟对象 List mockedList = mock(List....
通过本文的介绍,我们了解了Mocks的基本概念及其在单元测试中的重要作用,并深入探讨了如何使用Mockito来有效地进行模拟对象的创建、Stubbing以及验证行为等功能。Mockito的强大功能和简洁API使其成为Java开发者进行...