Mockito 验证超时在并发执行时不可预测地失败

Mockito verify with timeout failes unpredictably on concurrent execution

我刚刚编写了一个 Mockito 代码来测试 verify(mock, timeout()) 在模拟对象上同时调用方法时的功能。

@RunWith(Parameterized.class)
public class MockitoTest {
    @Parameters
    public static Collection<Object[]> data() {
        return Stream.generate(() -> new Object[]{}).limit(100).collect(Collectors.toList());
    }

    @Test
    public void testVerifyTimeout() throws Exception {
        List listMock = mock(List.class);
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        Stream.iterate(0, i -> i + 1).limit(10).map(i -> new AddToListTask(listMock, i)).forEach(executorService::submit);
        verify(listMock, timeout(1000)).add(2);
        executorService.shutdown();
    }

    private static class AddToListTask implements Callable<Void> {
        private final List<Integer> list;
        private final int value;

        public AddToListTask(List<Integer> list, int value) {
            this.list = list;
            this.value = value;
        }

        @Override
        public Void call() throws Exception {
            list.add(value);
            return null;
        }
    }
}

此测试在 100 运行 秒中随机失败 10-20 次。这是一个非常基本的情况,我们同时 运行 一个 mock 方法,结果并不总是被正确验证。 每次测试运行s大约25ms-50ms,但即使失败,也不会等待1秒。 有什么想法吗?

在 mockito 1.9.0 中,这是一个错误,但已经修复,因此从 1.9.5 版开始(包括 1.10.x、2.x)运行良好。