[英]Catch Java exception from Runnable in Unit test
我有以下代码
public final class JoinableTaskPool<T> extends ABC {
private int taskCounter;
private final Object monitor;
private final ExtendedThreadPoolExecutor service;
private final CompletionService<T> compService;
public Future<T> submit(final Callable<T> task) {
final Future<T> result = compService.submit(task);
service.submit(new Runnable() {
public void run() {
try {
final Future<T> result = compService.take();
try {
handler.processResult(result);
} catch (final Throwable t) {
throw new SearchException("Task has an error", t);
}
} catch (InterruptedException e) {
throw new SearchException("Task has an error", e);
}
}
}
return result;
}
public void join() {
synchronized (monitor) {
while (taskCounter != 0) {
try {
monitor.wait();
} catch (InterruptedException e) {
error(e, "Interrupted in join");
}
}
}
}
ExtendedThreadPoolExecutor class 定义如下
public class ExtendedThreadPoolExecutor extends ThreadPoolExecutor {
public ExtendedThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if(t != null) {
throw new SearchException("Error while executing the task", t);
}
}
}
我正在尝试为此方法编写单元测试。 下面是方法
@RunWith(MockitoJUnitRunner.class)
public class TestJoinableTaskPool<T> {
private JoinableTaskPool<T> pool;
@Before
public void setUp() {
pool = new JoinableTaskPool<T>(1);
}
@After
public void tearDown() {
pool.shutdown();
}
@Test (expected = SearchException.class)
public void testSubmit() throws Exception{
Callable task = (Callable<T>) () -> null;
Mockito.when(pool.getFinishHandler().processResult(result))
.thenThrow(RuntimeException.class);
pool.submit(task);
}
}
由于在runnable中抛出了SearchException异常,所以没有办法在submit方法之外访问它。 如果我会返回由executorService.submit
返回的 Future,我可以执行 future.get() 来获取异常,但我会返回另一个未来( result
变量)。 因此,在编写单元测试时,我无法抛出异常。
我还重写了 afterExecute() 以从单元测试中捕获异常,但找不到调用它的方法。
如何测试从单元测试的可运行对象抛出的异常。 任何帮助,将不胜感激。
撇开他的代码闻起来一英里远,你可以做的是创建额外的接口,例如
public interface MyErrorHandler { handleError(Exception e)
在您的执行程序池中实现它并在异常时调用它。 然后您可以使用Mockito.spy
来查看是否在MyErrorHandler
上调用了该方法(cglib 应该允许您这样做,即使没有额外的接口。)
或者,您可以定义应将MyExceptionHandler
实例传递给执行程序(通过构造函数或设置器),以便您能够提供此类回调的用例依赖实现
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.