非常小心,使用
times(0)
时要非常小心,因为它的工作方式可能与您期望的不同。
实际上,您可以尝试这段代码,以注意到超时实际上并没有达到,只要第一个有效的Mockito评估通过,
verify
断言就会通过。
private static class TestAsync {
void test() {
System.out.println("test");
}
}
@Test
void testAsyncWaitZeroTimes() {
var testAsync = Mockito.mock(TestAsync.class);
doCallRealMethod().when(testAsync).test();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
testAsync.test();
}
}, 1000);
verify(testAsync, timeout(2000).times(0)).test();
}
@Test
void testAsyncWaitOnce() {
var testAsync = Mockito.mock(TestAsync.class);
doCallRealMethod().when(testAsync).test();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
testAsync.test();
}
}, 1000);
verify(testAsync, timeout(2000).times(1)).test();
}
@Test
void testAsyncWaitReachingTimeout() {
var testAsync = Mockito.mock(TestAsync.class);
doCallRealMethod().when(testAsync).test();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
testAsync.test();
}
}, 2000);
verify(testAsync, timeout(1000).times(1)).test();
}
你会注意到
test
只在
testAsyncWaitOnce
测试中被打印出来。
我正在使用一个叫做
awaitility
的第三方库,它允许我们做一些像这样的事情:
@Test
void testAsyncWaitUsingAwaitilityShouldNotBeCalled() {
var testAsync = Mockito.mock(TestAsync.class);
doCallRealMethod().when(testAsync).test();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
testAsync.test();
}
}, 5000);
await().during(2, TimeUnit.SECONDS)
.until(() -> Try.run(() -> verify(testAsync, never()).test())
.isSuccess());
}
@Test
void testAsyncWaitUsingAwaitilityShouldBeCalledOnce() {
var testAsync = Mockito.mock(TestAsync.class);
doCallRealMethod().when(testAsync).test();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
testAsync.test();
}
}, 1000);
await().timeout(2, TimeUnit.SECONDS)
.until(() -> Try.run(() -> verify(testAsync, times(1)).test())
.isSuccess());
}
这样我们就可以看到时间是否正确等待,过去没有发生任何交互。