java mock测试_mockito_mock测试

mock其实是一种工具的简称,他最大的功能是帮你把单元测试的耦合分解开,如果你的代码对另一个类或者接口有依赖,它能够帮你模拟这些依赖,并帮你验证所调用的依赖的行为。

之前介绍了如何设置mock对象预期调用的方法及返回值。下面介绍方法调用的验证,而它关注点则在mock对象的交互行为上,比如验证mock对象的某个方法调用参数,调用次数,顺序等等。下面来看例子:

Java代码  收藏代码

@Test

public void verifyTestTest() {

List mock = mock(List.class);

List 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 firstMock = mock(List.class);

List 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对象中是否存在没有验证的调用方法,和顺序是无关的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值