如何只使用一个bean并包含reslience4j注释来运行SpringBootTest



我想在spring引导应用程序中运行一个带有resilience4j注释方法的单个bean的集成测试。我的意图是测试bean方法调用的弹性,同时不加载完整的spring上下文。

设置如下:

依赖项包括以下内容:

io.github.resilience4j:resilience4j-spring-boot2
io.github.resilience4j:resilience4j-reactor
org.springframework.boot:spring-boot-starter-aop

弹性4j时限弹簧豆的试验方法:

@Service
public class FooService {
@TimeLimiter(name = "fooTimeLimiter")
public FooResponse foo() {
//entertain operation that might timeout
}
}

配置:

resilience4j.timelimiter.instances.fooTimeLimiter.timeoutDuration=1s

测试:

@SpringBootTest
@ContextConfiguration(classes = FooService.class)
public class FooServiceIT {
@Autowired
private FooService service;

@MockBean
private Bar bar;
@Test
void foo_timeout() {
//setup mocks so the operation delays the output and shall end up with timeout

Assertions.assertThrows(TimeoutException.class, () -> service.foo());
}    
}

但是,TimeLimiterAdvice.proceed((不被接受,不会引发超时异常,并且测试失败。

这里也提出了同样的问题:使用注释样式Resilience4j测试SpringBoot,但没有解决方案。

我尝试了两种方法——直接使用具体类实现FooService接口和程序。同样的结果。

我如何才能在测试中考虑到时间限制注释?

编辑:我甚至尝试了以下设置的普通弹簧测试(没有弹簧引导(:

@ExtendWith(SpringExtension.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class FooServiceIT {
@Configuration
@Import({TimeLimiterConfiguration.class, FallbackConfiguration.class, SpelResolverConfiguration.class})
static class ContextConfiguration {
@Bean
public FooService fooService() {
//prepare bean;
}
@Bean
public TimeLimiterConfigurationProperties timeLimiterConfigurationProperties() {
return new TimeLimiterConfigurationProperties();
}
}
@Autowired
private FooService service;
//tests...
}

相同的结果(即没有超时异常(。

在处理SpringBootTest@CircuitBreaker时,将@EnableAspectJAutoProxy注释添加到测试中就足够了。在这一变化之后,CircuitBreakerAspect被接受,并且测试表现如预期。

为了使@TimeLimiter按预期工作,还需要向该方法添加@Bulkhead注释。

更新后的方法如下:

@Bulkhead(name = "fooBulkhead", type = Type.THREADPOOL)
@CircuitBreaker(
name = "fooCircuitBreaker",
fallbackMethod = "fooFallback"
)
@TimeLimiter(
name = "fooTimeLimiter"
)
public CompletableFuture<FooResponse> foo() {
//...
}

以及测试:

@SpringBootTest(classes = FooService.class)
@EnableAspectJAutoProxy
@Import(value = {CircuitBreakerAutoConfiguration.class, TimeLimiterAutoConfiguration.class, BulkheadAutoConfiguration.class})
public class FooServiceIT {
//...
}

最新更新