我遇到了一个非常奇怪的行为,以防我在测试期间更改模拟行为。我嘲笑一个非常简单的界面:
interface Bar {
String string(String str);
}
@Mock
private Bar bar;
然后,我调用它并计算使用AtomicInteger
调用的次数,这是这个最小工作示例的副作用。
@Test
public void test() {
AtomicInteger atomicInteger = new AtomicInteger(0);
// Mock with the increment
Mockito.when(bar.string(Mockito.anyString())).then(invocation -> {
log.info("MOCK - waiting (1): {}", invocation.getArguments()[0]);
atomicInteger.incrementAndGet();
log.info("MOCK - returning (1)");
return "BAR_1";
});
// Invocation of the increment
log.info("Result (1): " + bar.string("FOO_1"));
// Passes
Assertions.assertEquals(1, atomicInteger.get());
}
14:18:17.336 [main] INFO com.Foo - MOCK - waiting (1): FOO_1
14:18:17.343 [main] INFO com.Foo - MOCK - returning (1)
14:18:17.349 [main] INFO com.Foo - Result (1): BAR_1
只要使用bar.string("FOO_1")
一次明显地调用了该方法,测试就会通过。只要我在执行后添加模拟bar
的新行为以不增加AtomicInteger
,就会再次调用不应该调用的原始模拟:
@Test
public void test() {
AtomicInteger atomicInteger = new AtomicInteger(0);
// Mock with the increment
Mockito.when(bar.string(Mockito.anyString())).then(invocation -> {
log.info("MOCK - waiting (1): {}", invocation.getArguments()[0]);
atomicInteger.incrementAndGet();
log.info("MOCK - returning (1)");
return "BAR_1";
});
// Invocation with increment
log.info("Result (1): " + bar.string("FOO_1"));
/* NEW CODE BLOCK STARTS */
// Mock without the increment
Mockito.when(bar.string(Mockito.anyString())).then(invocation -> {
log.info("MOCK - returning (2): {}", invocation.getArguments()[0]);
return "BAR_2";
});
// Invocation without the increment
// The previous lines really changed the mock, but it was called one more times
log.info("Result (2): " + bar.string("FOO_2"));
/* NEW CODE BLOCK ENDS */
// Fails, it is 2
Assertions.assertEquals(1, atomicInteger.get());
}
14:19:31.603 [main] INFO com.Foo - MOCK - waiting (1): FOO_1
14:19:31.612 [main] INFO com.Foo - MOCK - returning (1)
14:19:31.620 [main] INFO com.Foo - Result (1): BAR_1
14:19:31.621 [main] INFO com.Foo - MOCK - waiting (1):
14:19:31.621 [main] INFO com.Foo - MOCK - returning (1)
14:19:31.623 [main] INFO com.Foo - MOCK - returning (2): FOO_2
14:19:31.624 [main] INFO com.Foo - Result (2): BAR_2
令人惊讶的是,日志显示调用模拟方法时第4行没有参数。
当我在同一个测试N
-times中包含更多这段代码时,行为不会改变。测试总是失败,期望增量是2
而不是1
。
Mockito.when(bar.string(Mockito.anyString())).then(invocation -> {
log.info("MOCK - returning (N): {}", invocation.getArguments()[0]);
return "BAR_N";
});
log.info("Result (N): " + bar.string("FOO_N"));
是什么使Mockito在测试1+期间更改其行为后,精确地调用了带有模拟参数的模拟方法一次?
发布于 2020-07-22 13:01:21
在remocking操作中调用bar.string(Mockito.anyString())
仍然等同于bar.string(String)
调用,之前曾对此进行过模拟,以增加AtomicInteger
。
log.info("Result (1): " + bar.string("FOO_1")); // Increases to 1
Mockito.when(bar.string(Mockito.anyString())).then(invocation -> { // Increases to 2
在删除之后,当新的模拟生效时,这个数字不再增加。您应该使用clean mocks来避免编写脆弱或复杂的测试代码。
https://stackoverflow.com/questions/63034242
复制相似问题