编写JUnit测试覆盖catch块遇异常抛出问题求助
问题排查与解决方案
核心错误分析
你的测试代码存在两个关键问题:
- 错误地直接模拟被测试方法抛出异常:
when(service.doCreate(subscription)).thenThrow(...)的用法完全错误——service是你要测试的真实实例(而非Mock对象),不能直接强制它抛出异常。正确的做法是模拟service的依赖(即snsProducer)抛出JsonProcessingException,从而触发service.doCreate()中的捕获逻辑。 - 受检异常的非法抛出:
JsonProcessingException是受检异常,而doCreate()方法本身并未声明抛出该异常,直接强制它抛出会触发“Checked exception is invalid for this method!”错误。
修正后的测试用例
@Test void doCreateTest() { String id = RandomStringUtils.randomAlphanumeric(20); Subscription subscription = testUtils.createEntity(id, RandomStringUtils.randomAlphanumeric(20)); Manifest manifest = new Manifest(); manifest.setCommon(new Common()); // Mock manifestUtils的行为(这部分原代码是对的) doReturn(manifest).when(manifestUtils).getManifestWithLatestVersion(any()); // 关键:Mock snsProducer的send方法抛出JsonProcessingException // 因JsonProcessingException是抽象类,需创建匿名子类实例;根据send方法的实际参数调整匹配器 doThrow(new JsonProcessingException("Test exception") {}).when(snsProducer).send(any()); // 验证是否抛出预期的SnSException assertThrows(SnSException.class, () -> service.doCreate(subscription)); }
额外注意事项
- 确保
snsProducer在测试类中被正确标记为@Mock,且service通过@InjectMocks注入依赖,保证Mock对象能被真实的service实例调用。 - 根据
snsProducer.send()方法的实际参数类型调整匹配器:如果方法接收的是特定类型(比如自定义Message对象),将any()替换为any(Message.class)等精准匹配器,避免Mock不生效。 - 若
service.doCreate()中存在分支逻辑,需确保测试数据能进入调用snsProducer.send()的代码路径,否则仍会出现“未抛出预期异常”的问题。
内容的提问来源于stack exchange,提问作者Doctor Who
相关产品推荐
相关产品推荐

