Mockito:如何统计经Spring AOP重试且抛异常的方法调用次数?
解决方案:用断言捕获异常后再验证调用次数
当然可以用Mockito统计调用次数,核心问题是避免让异常提前终止测试方法,导致后续的verify步骤无法执行。你之前用@Test(expected = ...)的方式会在异常抛出时直接结束测试,跳过验证;直接调用方法又会因为异常未被捕获导致测试失败,verify根本没机会执行。
解决方法是用断言API主动捕获异常,完成业务逻辑执行后,再执行Mockito的验证步骤,具体实现如下:
步骤1:选择合适的异常捕获方式
JUnit 5 写法
用Assertions.assertThrows包裹触发重试逻辑的代码,它会捕获最终抛出的异常,同时保证后续代码能正常执行:
@Test void testRetryInvocationCount() { // 1. 模拟目标方法每次调用都抛出业务异常(模拟数据库无数据场景) doThrow(YourBusinessNotFoundException.class).when(yourDaoMock).queryData(); // 2. 捕获最终抛出的异常,同时执行完整的重试逻辑 Assertions.assertThrows(YourBusinessNotFoundException.class, () -> { // 调用触发重试的业务方法(比如service层的方法) yourService.queryWithRetry(); }); // 3. 此时验证目标方法被调用了5次 verify(yourDaoMock, times(5)).queryData(); }
JUnit 4 写法
如果还用JUnit 4,可以用ExpectedException规则,或者JUnit 4.13+支持的Assert.assertThrows:
@Rule public ExpectedException exceptionRule = ExpectedException.none(); @Test void testRetryInvocationCount() { doThrow(YourBusinessNotFoundException.class).when(yourDaoMock).queryData(); // 预期最终抛出指定异常 exceptionRule.expect(YourBusinessNotFoundException.class); // 执行业务方法 yourService.queryWithRetry(); // 验证调用次数 verify(yourDaoMock, times(5)).queryData(); }
关键注意点
- 确保Spring AOP的重试逻辑在测试环境中生效:如果是XML配置的AOP,要在测试类中正确加载对应的Spring配置文件,保证目标bean是被AOP代理后的实例(不要直接new对象,要通过Spring容器获取)。
- 模拟异常时,要确保抛出的异常类型和业务逻辑中定义的一致,否则重试逻辑可能不会触发(比如重试配置可能指定了只重试特定异常)。
内容的提问来源于stack exchange,提问作者Konstantin
相关产品推荐
相关产品推荐

