Spring @Retryable按条件切换拦截器的测试实现方案问询
方案1:直接校验拦截器实例的内部策略(零业务代码改动)
这是成本最低的方案,完全不需要修改现有业务实现,仅需在测试用例中直接判断注入的myInterceptor实例所持有的重试策略即可:
// 测试类1:开启重试配置的场景 @SpringBootTest(properties = "your.retry.property.enabled=true") class RetryEnabledTest { @Autowired private RetryOperationsInterceptor myInterceptor; @Test void shouldUseRealRetryPolicy() { // 断言当前拦截器的重试策略不是永不重试策略 assertThat(myInterceptor.getRetryOperations().getRetryPolicy()) .isNotInstanceOf(NeverRetryPolicy.class); } } // 测试类2:关闭重试配置的场景 @SpringBootTest(properties = "your.retry.property.enabled=false") class RetryDisabledTest { @Autowired private RetryOperationsInterceptor myInterceptor; @Test void shouldUseNeverRetryPolicy() { // 断言当前拦截器使用了永不重试策略 assertThat(myInterceptor.getRetryOperations().getRetryPolicy()) .isInstanceOf(NeverRetryPolicy.class); } }
方案2:给Bean增加别名区分(仅需追加2行注解)
如果你不想依赖框架内部属性的耦合判断,可以给两个Bean追加不同的限定符别名,主名称保持myInterceptor不受影响:
@Bean @ConditionalOnMyPropertyEnabled @Qualifier("retryEnabledInterceptor") // 追加别名 public RetryOperationsInterceptor myInterceptor() { return // 实际重试的拦截器 } @Bean("myInterceptor") @ConditionalOnMyPropertyDisabled @Qualifier("retryDisabledInterceptor") // 追加别名 public RetryOperationsInterceptor myNeverRetryInterceptor() { return RetryInterceptorBuilder.stateless().retryPolicy(new NeverRetryPolicy()).build(); }
测试时通过别名注入判断存在性即可:
@SpringBootTest(properties = "your.retry.property.enabled=true") class RetryEnabledTest { @Autowired(required = false) @Qualifier("retryEnabledInterceptor") private RetryOperationsInterceptor enabledInterceptor; @Autowired(required = false) @Qualifier("retryDisabledInterceptor") private RetryOperationsInterceptor disabledInterceptor; @Test void shouldLoadCorrectInterceptor() { assertThat(enabledInterceptor).isNotNull(); assertThat(disabledInterceptor).isNull(); } }
方案3:黑盒测试实际重试行为(最贴近真实业务效果)
直接测试Dummy.getResponse的调用行为,不需要关心内部Bean实现,验证结果符合预期即可:
- Mock
getResponse的底层依赖让它固定抛出异常 - 开启重试配置时,验证底层依赖被调用的次数等于
最大重试次数+1 - 关闭重试配置时,验证底层依赖仅被调用1次
内容的提问来源于stack exchange,提问作者Eugene
相关产品推荐
相关产品推荐

