如何 运行 SpringBootTest 只有一个 bean 并包含 resilience4j 注释
How to run the SpringBootTest with only a single bean and with included resilience4j annotations
我想 运行 在 spring 启动应用程序中使用 resilience4j 注释方法对单个 bean 进行集成测试。我的目的是在不加载完整 spring 上下文的情况下测试 bean 方法调用的弹性。
设置如下:
依赖项包括以下内容:
io.github.resilience4j:resilience4j-spring-boot2
io.github.resilience4j:resilience4j-reactor
org.springframework.boot:spring-boot-starter-aop
resilience4j time limited spring bean with method to test:
@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()没有被接受,没有抛出超时异常,测试失败。
这里有人问过同样的问题:Testing SpringBoot with annotation-style Resilience4j但是没有解决方案。
我尝试了两种方法 - 实现 FooService 接口并直接使用具体的程序 class。结果一样。
如何在我的测试中考虑时间限制器注释?
编辑:我什至尝试使用以下设置进行普通 spring 测试(没有 spring 引导):
@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 {
//...
}
我想 运行 在 spring 启动应用程序中使用 resilience4j 注释方法对单个 bean 进行集成测试。我的目的是在不加载完整 spring 上下文的情况下测试 bean 方法调用的弹性。
设置如下:
依赖项包括以下内容:
io.github.resilience4j:resilience4j-spring-boot2
io.github.resilience4j:resilience4j-reactor
org.springframework.boot:spring-boot-starter-aop
resilience4j time limited spring bean with method to test:
@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()没有被接受,没有抛出超时异常,测试失败。
这里有人问过同样的问题:Testing SpringBoot with annotation-style Resilience4j但是没有解决方案。
我尝试了两种方法 - 实现 FooService 接口并直接使用具体的程序 class。结果一样。
如何在我的测试中考虑时间限制器注释?
编辑:我什至尝试使用以下设置进行普通 spring 测试(没有 spring 引导):
@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 {
//...
}