[英]Mockito when() in parallel stream unexpected result
我在我们的一项测试中调查了 Mockito 的行为,但我不理解它的行为。 以下代码片段显示了相同的行为:
@Test
public void test(){
var mymock = Mockito.mock(Object.class);
var l = List.of(1,2,3);
l.parallelStream().forEach(val -> {
int finalI = val;
doAnswer(invocationOnMock -> {
log.info("{}",finalI);
return null;
}).when(mymock).toString();
mymock.toString();
});
}
我期待的 output 是按某种顺序打印的 1,2,3(不是 nessaseraly 排序的):
我收到的 output:
2
2
2
为什么我得到这个 output?
这是一个经典的竞争条件:您的并行 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 并行执行forEach
lambda 三次。 在这种情况下,所有三个线程都设法执行了doAnswer()
调用,然后它们中的任何一个都到达了mymock.toString()
行。 恰好val=2
的执行恰好最后运行。 令人高兴的是,Mockito 是相当线程安全的,因此您不会只是抛出异常。
您的情况可能发生的一种方式是,如果线程碰巧像这样运行:
l.parallelStream().forEach()
,它产生 3 个线程,其val
等于 1、2 和 3finalI=val
,在这个线程中给它一个值 1finalI=val
,在这个线程中给它一个值 2finalI=val
,在这个线程中给它一个值 3doAnswer(...)
这使得将来调用mymock.toString()
打印出3
doAnswer(...)
这使得将来调用mymock.toString()
打印出1
doAnswer(...)
这使得将来调用mymock.toString()
打印出2
mymock.toString()
,打印出2
mymock.toString()
,打印出2
mymock.toString()
,打印出2
请注意,这不一定按顺序发生,甚至不一定按此顺序发生:
因为线程是并行运行的,而您没有安排任何东西来管理它,所以无法保证这些调用发生的顺序:您的 output 可能很容易是1 1 1
, 1 2 3
, 3 2 1
或3 2 2
或1 1 3
等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.