JUnit assertThrows通过但ExpectedException捕获异常失效问题
问题根本原因
核心诱因是JUnit 4与JUnit 5的API混用,导致ExpectedException规则完全没有生效:
Assertions.assertThrows是JUnit 5(Jupiter)的原生断言API,它会自主捕获传入lambda执行时抛出的异常,直接匹配异常类型,不依赖测试框架的规则扩展机制,因此可以正常通过校验。@Rule注解、ExpectedException类都是JUnit 4版本的专属扩展机制,JUnit 5默认的Jupiter测试引擎根本不会识别、加载JUnit4的@Rule注解,你声明的expectedException实例完全没有被注册到测试执行流程中,根本不会触发异常捕获逻辑。- 这种情况下
methodBeingTested()抛出的MyCustomException没有被任何测试逻辑捕获,直接抛给测试运行器,自然会导致测试失败,和你指定的异常类型是否准确没有关系。你贴出的日志里进程退出码为-1,就是未捕获异常直接终止测试进程的典型表现。
正确处理方式
如果当前使用JUnit 5环境,完全没必要引入JUnit4的ExpectedException规则,直接利用assertThrows的返回值就能完成异常类型、异常信息、异常原因的全量校验:
@Test void test() { // 校验异常类型同时捕获异常实例 MyCustomException ex = Assertions.assertThrows( MyCustomException.class, () -> methodBeingTested()); // 按需校验异常消息、根因等内容 Assertions.assertEquals("预期异常提示内容", ex.getMessage()); }
如果一定要使用ExpectedException,需要将测试整体迁移到JUnit4环境:替换@Test注解为org.junit.Test,确保测试运行器为JUnit4 Vintage引擎,不要混用JUnit5的Assertions类。
内容的提问来源于stack exchange,提问作者Mateus Ramos
相关产品推荐
相关产品推荐

