如何仅使用单个 bean 并使用包含的resilience4j注释来运行SpringBootTest

2024-02-14

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

设置如下:

依赖项包括以下内容:

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 https://stackoverflow.com/questions/65103654/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...
}

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


当处理SpringBootTest and @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 {
    //...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何仅使用单个 bean 并使用包含的resilience4j注释来运行SpringBootTest 的相关文章

随机推荐