`
hotdog
  • 浏览: 284698 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

学习Mockito - Mock对象的行为验证

    博客分类:
  • test
 
阅读更多
之前介绍了如何设置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-1.9.5.zip

    Mockito 是一个流行的Java单元测试框架,用于模拟对象行为,使得测试更为简洁和可控。JUnit则是最常用的Java单元测试库,它提供了一种结构化的方式来编写和运行测试用例。当我们进行单元测试时,Mockito 和 JUnit ...

    mock开发所用到的2个核心JAR

    2. **Stubbing**:这是定义mock对象行为的过程。你可以指定当特定的方法被调用时,mock对象应该如何响应。例如,你可以设置mock对象在某个方法被调用时返回特定的值。 3. **Verification**:Mockito提供了一种验证...

    Mockito-Programming-Cookbook

    - 使用 Mockito 来模拟依赖对象,并编写测试用例来验证类的行为。 4. **添加行为:** - 使用 `when()` 方法来设置模拟对象的行为。 - 示例:`when(mockObject.methodName()).thenReturn(value);` 5. **验证行为...

    mockito-kotlin:将Mockito与Kotlin一起使用

    2. **配置mock行为**:使用`whenever`关键字和lambda表达式来定义mock对象的行为,如`whenever(myMock.someMethod()).thenReturn(someValue)`。 3. **验证方法调用**:使用`verify`函数来检查方法是否被正确调用,如...

    MockitoProject_tool_mockito-1.8.5.jar_storefh5_

    为了有效地利用“mockito-1.8.5.jar”,开发者需要将其添加到项目的类路径中,然后使用Mockito提供的API来创建mock对象,设置期望行为,并进行验证。同时,理解如何将Mockito与其他测试框架集成也是关键,这可能涉及...

    PowerMock+Mockito-junit测试套件1.6.3版本

    1. **Mock对象创建**:Mockito可以轻松地创建mock对象,模拟对象的行为,而不涉及实际的实现。 2. **验证方法调用**:Mockito的`verify()`方法用于检查特定方法是否按预期被调用,以及调用次数和参数。 3. ** ...

    powermock-mockito-junit-1.6.2.zip

    4. 使用Mockito的API创建mock对象并设置期望行为。 5. 使用PowerMock的API模拟静态方法、final类或方法等。 6. 编写测试方法,调用要测试的代码,并使用Mockito验证方法调用是否符合预期。 通过以上步骤,开发者...

    powermock-mockito-junit-1.6.3.zip 当前最新版

    PowerMock 是一个扩展了其他Mock框架(如Mockito)的库,它允许开发者模拟那些通常无法被模拟的行为。在某些场景下,例如当你的代码依赖于静态方法或静态初始化块时,PowerMock 可以帮助你创建隔离的测试环境,以便...

    PyPI 官网下载 | mockito-1.0.9.tar.gz

    在Python中使用Mockito时,开发者通常会在测试代码中导入mockito库,然后使用`mock`、`patch`等函数来创建和配置模拟对象。例如,如果有一个函数`foo`依赖于外部服务`bar`,可以使用Mockito创建`bar`的模拟对象,...

    spring-mock.jar

    1. 模拟对象(Mock Object):模拟对象是真实对象的替代品,它可以预定义行为和返回值,以便在测试中控制依赖对象的行为。 2. 验证(Verification):验证是检查模拟对象在测试期间是否按照预期执行了某些操作,如...

    Mockito-and-Junit:Java Mock deafferents方法的示例存储库

    Mockito 还提供了验证功能,可以检查 mock 对象的方法是否按预期被调用了。例如,`verify(mockObject).someMethod()` 会确保 `someMethod()` 被调用了一次。 5. **Stubbing( stubs)**: Stubbing 是指预先定义...

    mockito-sample:在JUnit测试用例中如何使用Mockito创建模拟对象的快速示例

    通过学习这个示例,开发者可以了解如何在实际项目中使用 Mockito 和 JUnit 进行单元测试,包括如何创建模拟对象、预定义行为、验证方法调用等。这对于提高代码质量、确保功能正确性至关重要,特别是在大型复杂项目中...

    Android-Test-With-JUnit-Mockito-RoboElectric

    在Android测试中,Mockito允许我们创建“mock”对象,即代替真实对象的替身,这些mock对象可以在测试中替代真实的依赖,避免了实际调用其他组件可能带来的复杂性。例如,我们可以通过`@Mock`注解创建mock对象,然后...

    Espresso-And-Mockito-Sample

    Espresso 是 Google 推出的用于 Android 应用程序的 UI 测试工具,而 Mockito 是一个流行的 Java 单元测试框架,它允许开发者模拟对象行为以便于测试。 **Espresso** 是一个强大的 Android 测试框架,主要用于编写...

    Mockito-with-Junit:与Junit嘲笑

    Mockito 还提供了许多高级特性,如 spy 对象(部分模拟对象)、argument matchers(匹配器)以及验证方法调用的顺序等。这些功能可以帮助我们编写更复杂的测试场景。 ### 10. 结论 通过结合 Mockito 和 JUnit,...

    springboot + mockito 使用示例代码-原创

    Mockito是一个流行的Java单元测试框架,它允许我们创建和配置模拟对象,以便在测试中隔离我们想要验证的代码部分。结合Spring Boot,我们可以确保我们的应用程序组件在独立环境中运行,不受其他依赖的影响。 首先,...

    My-Mockito-Framework:Mockito在内部如何工作?

    Mock对象完全不执行实际的方法,而是记录调用历史;而Spy对象则是在真实对象的基础上创建的,它会执行实际的方法,但允许你为某些特定行为设置模拟。 在Mockito中,你可以使用`when()`方法来定义模拟对象的预期行为...

    mockito-hamcrest:Mockito和Hamcrest Matchers课程示例

    Mockito提供了一种简洁的API,通过`mock()`方法创建模拟对象,通过`when()`定义模拟对象的行为,通过`verify()`检查模拟对象的方法是否被正确调用。例如: ```java // 创建模拟对象 List mockedList = mock(List....

    Mocks, Mockito, and Spock

    通过本文的介绍,我们了解了Mocks的基本概念及其在单元测试中的重要作用,并深入探讨了如何使用Mockito来有效地进行模拟对象的创建、Stubbing以及验证行为等功能。Mockito的强大功能和简洁API使其成为Java开发者进行...

Global site tag (gtag.js) - Google Analytics