就可重现的例子而言,我有以下课程
public class SampleCaching {
ScheduledExecutorService executorService;
@com.google.inject.Inject InterestCache interestCache;
@Inject MultimediaCache multimediaCache;
@Inject
public SampleCaching(InterestCache interestCache, MultimediaCache multimediaCache) {
this.executorService = Executors.newScheduledThreadPool(3);
this.interestCache = interestCache;
this.multimediaCache = multimediaCache;
}
protected void calculate() {
interestCache.populateOne();
interestCache.populateTwo();
multimediaCache.populateMultimedia();
log.info("Cache population completed!");
}
public void start() {
executorService.scheduleAtFixedRate(this::calculate,
0, 20, TimeUnit.MINUTES); // notice initial delay
}
}
而且似乎事实是我为此代码编写了一个半错误的单元测试,其内容为:
@org.junit.runner.RunWith(PowerMockRunner.class)
@org.powermock.core.classloader.annotations.PowerMockIgnore("javax.management.*")
public class SampleCachingTest {
@org.mockito.Mock InterestCache interestCache;
@Mock MultimediaCache multimediaCache;
@org.mockito.InjectMocks SampleCaching sampleCaching;
@Test
public void testInvokingStart() throws Exception {
sampleCaching.start();
verify(multimediaCache, times(0)).populateMultimedia();
verify(interestCache, times(0)).populateOne();
verify(interestCache, times(0)).populateTwo();
}
}
scheduleAtFixedRate
的返回类型,并且无论如何模拟都可以正常工作?ScheduledExecutorService
测试没有多大关系(至少这是我目前的想法)。[[我说,是半不正确的,因为如果我增加实际代码中的初始延迟来举例说明1 MINUTE
,则该测试通过。真正让我问这个问题的是,如果我将测试更改为
@Test
public void testInvokingStart() throws Exception {
sampleCaching.start();
verify(interestCache, times(1)).populateOne();
verify(interestCache, times(1)).populateTwo();
}
它总是成功执行,但为多媒体添加verify
却总是使测试失败:
verify(multimediaCache, times(1)).populateMultimedia(); // or even to `times(0)`
就可复制的示例而言,我有以下公共类SampleCaching {ScheduledExecutorService executorService; @ com.google.inject.Inject InterestCache interestCache; ...这种行为(确定性或确定性)背后有原因吗?修复此测试的正确方法是什么?