java - JUnit/Mockito : throwing an exception in a new thread

标签 java spring junit mockito

我正在为其编写单元测试的以下 Java 代码:

try {
    new Thread(() -> myService.myMethod()).start();
    return new MyResponse("Done");
} catch (Exception exception) {
    throw new MyException("Internal Error", exception);
}

我试图模拟 myService.myMethod() 抛出错误,以便在上面代码的 catch block 中捕获该错误并抛出一个 MyException 实例。

在我的 JUnit 测试中(使用 org.springframework.test.context.junit4.SpringJUnit4ClassRunner 和 Mockito),我模拟了 MyService 并将其作为 Spring bean 注入(inject)到单元测试中:

MyService myService = Mockito.mock(MyService.class);

然后我尝试用这个来模仿服务抛出异常:

IllegalArgumentException myException = new IllegalArgumentException();
Mockito.doThrow(myException).when(myService).myMethod();

...但是我正在测试的方法的 catch block 中永远不会捕获异常。

这可能与代码使用另一个线程调用 myService.myMethod() 有关。

有什么方法可以正确捕获 myService.myMethod() 抛出的异常吗?

预先感谢您的帮助。

最佳答案

“外部”线程可以捕获另一个线程中的异常是没有意义的。 如果您向代码添加上下文,例如

Thread th = new Thread(() -> { Thread.sleep(10000); throw new RuntimeException(); });
try { th.start(); } catch (Exception e) {
    System.out.println("uh-oh");
}
for (int i = 0; i < 1000; i++){
    System.out.println("running " + i);
    Thread.sleep(1000);
}

线程启动,10秒后抛出异常。然而,起始线程已经开始每秒计数。如果启动线程的异常被捕获,您是否希望主线程返回到捕获异常的地方?是否应该中断计数然后继续?不继续吗?

您能做的最好的事情可能是指定一个错误处理程序(就像罗杰在他的评论中提到的那样),但是您必须以实际的时间间隔从主线程查询其状态,因为它将在并发启动的线程中运行。

考虑t = new Thread(); t.start(); 不建议再使用,最简单的方法是使用 CompletableFuture IMO:

CompletableFuture<Void> future = 
    CompletableFuture.runAsync(() -> myService.myMethod());

现在您可以稍后查询发生了什么:

if (future.isDone()) // task has finished in any way

if (future.isDone() && future.isCompletedExceptionally()) // task was finished because an exception was thrown

关于java - JUnit/Mockito : throwing an exception in a new thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61947090/

相关文章:

java - Docusign API - 如何在信封 (XML) 中设置过期通知

java - 如何加载属性文件并将其传递给 java 单例(枚举)

spring - 启用身份验证时如何配置spring boot admin客户端?

java - 对于模拟对象,Mockito 休息模板始终为空

java - 通过套接字从 Java 程序向 C 程序发送数据

java - 如何使用 JDBC 在一个事务中执行 2 个更新查询

java - 没有 @EnableAspectJAutoProxy,Spring AOP 能工作吗?

java - 用于字符串列表的 Initbinder

java - 如何为 Jmeter Junit Sampler 创建更详细的结果消息传递

java - Maven surefire testng 提供程序运行 JUnit 测试,但不报告结果