待测代码通过Callable
执行一组ExecutorService.invokeAll()
个对象。然后调用ExecutorService
线程池shutdown()
并调用awaitTermination()
。
ExecutorService threadpool = Executors.newFixedThreadPool(healthChecks.size());
List<Future <HealthStatus> > checkResults = threadpool.invokeAll(healthChecks);
threadpool.shutdown();
// Now wait for all the threads to finish as part of the shutdown.
if (!threadpool.awaitTermination(STATUS_CHECK_TIMEOUT_SECONDS, TimeUnit.SECONDS))
{
throw new Exception("Health checks did not all complete in time.");
}
我想对awaitTermination()
超时进行单元测试。
现在,我可以注入我自己的Callable
个对象来运行,所以我创建了一个单独使用会导致超时的对象。该对象的类看起来像这样(使用ConcurrentUnit.Waiter
对象):
public static final class TimeoutHealthCheck implements HealthChecker
{
public final long SleepIntervalMillis;
String healthName;
boolean result;
Waiter waiter;
public TimeoutHealthCheck(long timeoutInMillis, boolean result, String healthName, Waiter waiter) {
SleepIntervalMillis = timeoutInMillis;
this.healthName = healthName;
this.result = result;
this.waiter = waiter;
}
public HealthStatus call() throws Exception {
Thread.sleep(SleepIntervalMillis);
if (waiter != null) {
waiter.resume();
}
return new TestHealthStatus(healthName,result);
}
}
但是,当我运行JUnit测试时,它立即完成(我无法确认在测试代码中是否采用了超时路径)。
@Test(expected = java.lang.Exception.class)
public void testStatusTimeout() throws Exception {
final Waiter waiter = new Waiter();
HealthChecker checker = new TimeoutHealthCheck(
ServerStatusCheck.STATUS_CHECK_TIMEOUT_SECONDS*1000*2,
true,
"testStatusTimeout",
waiter);
Collection<HealthChecker> testCollect = new ArrayList<HealthChecker>(1);
testCollect.add(checker);
ServerStatusCheck checkUnderTest =
new ServerStatusCheck(testCollect, new DefaultDateTimeProvider());
checkUnderTest.Status();
waiter.await(ServerStatusCheck.STATUS_CHECK_TIMEOUT_SECONDS*1000*3);
}
我已经在使用ConcurrentUnit
Maven套餐(0.4.1),但要么我误解了服务员做了什么,要么就是没有正确的方向。
如果重要的话,我在Eclipse和Java 8下运行JUnit。