如何在Spring测试中用MockMvc验证RetryPolicy的执行?
在Spring测试中验证RetryPolicy执行的简便方法
核心思路:用Mock/Spy替换依赖,统计调用次数
你当前用真实Autowired Bean无法追踪调用情况,核心解决办法是利用Spring测试提供的Mock/Spy工具替换目标Bean,既能保留原有逻辑(或按需控制行为),又能精准验证调用次数。
方法一:Mock ServiceA,通过调用次数验证重试逻辑
既然重试由ServiceA抛出AccountNotFoundException触发,用@MockBean替换真实ServiceA,控制它每次调用都抛出异常,再统计调用次数是否匹配你的重试策略配置:
@SpringBootTest @AutoConfigureMockMvc class ControllerRetryTest { @Autowired private lateinit var mockMvc: MockMvc @MockBean private lateinit var serviceA: ServiceA @Test fun `当ServiceA抛异常时,RetryPolicy应执行重试`() { // 配置Mock:每次调用校验方法都抛出指定异常 given(serviceA.validateAccount(anyString())) .willThrow(AccountNotFoundException::class.java) // 发送请求触发控制器逻辑 mockMvc.perform(get("/your-api-path") .param("accountId", "test-account")) .andExpect(status().isInternalServerError) // 根据你的实际返回状态调整 // 验证调用次数:初始1次 + 重试次数(比如重试2次的话,总调用3次) verify(serviceA, times(3)).validateAccount(anyString()) } }
注意times(3)要对应你RetryPolicy的配置,比如maxAttempts = 3时,总调用次数就是3次。
方法二:Spy自定义RetryPolicy,直接验证其方法调用
如果你的RetryPolicy是自定义类,用@SpyBean包装真实实例,既能保留原有重试逻辑,又能直接验证重试方法的调用次数:
@SpringBootTest @AutoConfigureMockMvc class ControllerRetryTest { @Autowired private lateinit var mockMvc: MockMvc @MockBean private lateinit var serviceA: ServiceA @SpyBean private lateinit var retryPolicy: RetryPolicy @Test fun `验证RetryPolicy的重试逻辑被执行`() { given(serviceA.validateAccount(anyString())) .willThrow(AccountNotFoundException::class.java) mockMvc.perform(get("/your-api-path") .param("accountId", "test-account")) // 验证重试方法的调用次数(比如重试2次就填times(2)) verify(retryPolicy, times(2)).retry(any()) } }
这里的次数是重试的次数,而非总调用次数,要注意区分。
补充:如果用Spring Retry框架的@Retryable
如果重试是通过@Retryable注解实现的,除了上述验证ServiceA调用次数的方法,也可以通过自定义RetryListener监听重试事件,但Mock方法更直接简便。
内容的提问来源于stack exchange,提问作者HomeLighter
相关产品推荐
相关产品推荐

