单元测试方式执行次数的断言

关于org.mockito.Mockito.verify()方法断言调用次数的一些细节

背景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* Verifies certain behavior happened at least once / exact number of times / never. E.g:
* <pre class="code"><code class="java">
* verify(mock, times(5)).someMethod("was called five times");
*
* verify(mock, atLeast(2)).someMethod("was called at least two times");
*
* //you can use flexible argument matchers, e.g:
* verify(mock, atLeastOnce()).someMethod(<b>anyString()</b>);
* </code></pre>
*
* <b>times(1) is the default</b> and can be omitted
* <p>
* Arguments passed are compared using <code>equals()</code> method.
* Read about {@link ArgumentCaptor} or {@link ArgumentMatcher} to find out other ways of matching / asserting arguments passed.
* <p>
*
* @param mock to be verified
* @param mode times(x), atLeastOnce() or never()
*
* @return mock object itself
*/
@CheckReturnValue
public static <T> T verify(T mock, VerificationMode mode) {
return MOCKITO_CORE.verify(mock, mode);
}

方法注释中只写了第二个参数的使用方式,但是没有指出第二个参数的生命周期。


因此我有以下问题:

  • 多次执行被mock方法后,只调用一次verify,其次数如何断言?
  • 同一个被mock bean,通过改变被mock方法的参数调用,verify如何分别断言不同参数的调用?
  • 相同的mock调用(不改变参数),和verify交叉调用,次数应该如何断言,即次数是否会累计计算?

实验

问题1:

多次执行被mock方法后,只调用一次verify,其次数如何断言?

代码如下:

1
2
3
4
5
6
7
8
9
10
ConsumeHandler handler = mock(ConsumeHandler.class);

handler.consume(null,null,null,10);
handler.consume(null,null,null,10);
handler.consume(null,null,null,10);
handler.consume(null,null,null,10);


verify(handler,times(4)).consume(isNull(),isNull(),isNull(),eq(10));
verify(handler,times(4)).consume(isNull(),isNull(),isNull(),eq(10));

总结:

单纯的调用verify,其次数确实和调用次数相关;要特别注意的是,多次verify次数是累计计算,并不会出现因为上次verify了而重新开始计算

问题2:

同一个被mock bean,通过改变被mock方法的参数调用,verify如何分别断言不同参数的调用?

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
ConsumeHandler handler = mock(ConsumeHandler.class);


handler.consume(null,null,null,10);
handler.consume(null,null,null,1);
handler.consume(null,null,null,1);
handler.consume(null,null,null,14);


verify(handler,times(1)).consume(isNull(),isNull(),isNull(),eq(10));
verify(handler,times(2)).consume(isNull(),isNull(),isNull(),eq(1));
verify(handler,times(4)).consume(isNull(),isNull(),isNull(),anyInt());

总结:

次数和参数相关,只有满足了参数匹配的调用才会被计算次数

问题3:

相同的mock调用(不改变参数),和verify交叉调用,次数应该如何断言,即次数是否会累计计算?

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ConsumeHandler handler = mock(ConsumeHandler.class);


handler.consume(null,null,null,10);

verify(handler,times(1)).consume(isNull(),isNull(),isNull(),eq(10));

handler.consume(null,null,null,10);

verify(handler,times(2)).consume(isNull(),isNull(),isNull(),eq(10));

handler.consume(null,null,null,10);
handler.consume(null,null,null,10);

verify(handler,times(4)).consume(isNull(),isNull(),isNull(),eq(10));

总结:

可以看出,次数只和调用verify之前,执行了多少次符合参数匹配的方式有关,与verify调用次数无关


单元测试方式执行次数的断言
http://blog.inkroom.cn/2020/07/06/MTZ194.html
作者
inkbox
发布于
2020年7月6日
许可协议