【问题标题】:How to run the SpringBootTest with only a single bean and with included resilience4j annotations如何仅使用单个 bean 并包含弹性 4j 注释运行 SpringBootTest
【发布时间】:2022-01-22 05:37:31
【问题描述】:

我想在 Spring Boot 应用程序中运行具有弹性 4j 注释方法的单个 bean 的集成测试。我的目的是测试 bean 方法调用的弹性,同时不加载完整的 spring 上下文。

设置如下:

依赖包括以下内容:

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

resilience4j限时spring bean及测试方法:

@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 接口和程序。结果相同。

如何实现在我的测试中考虑时间限制器注释?

编辑:我什至尝试了以下设置的普通弹簧测试(没有弹簧靴):

@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...
}

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

【问题讨论】:

    标签: spring-test spring-boot-test resilience4j


    【解决方案1】:

    在处理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 {
        //...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-24
      • 2019-01-10
      • 2021-01-23
      • 2018-03-13
      • 1970-01-01
      • 2019-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多