同一类中为Micronaut集成测试配置两个不同固定时钟的问题
在同一Micronaut测试类中为不同测试方法注入不同固定Clock
我需要在同一个Micronaut集成测试类的两个独立测试方法中,分别使用两个不同的固定Clock实例(一个设为1800年10月10日,另一个设为1900年10月10日),但当前使用@MockBean结合@Requires的方案无法生效。尝试过通过自定义Service提供Clock,但该方案仅适用于直接调用Service的场景,无法满足服务层通过依赖注入使用Clock的需求,且希望在同一测试文件内解决问题,不拆分测试类。
方案一:基于配置属性动态生成Clock Bean
这种方式通过配置属性控制Clock的固定时间,结合@MicronautTest(rebuildContext = true)为每个测试方法重建上下文,从而实现不同测试使用不同的Clock。
步骤1:定义Clock Provider Bean
创建一个根据配置属性生成固定Clock的Bean(可放在测试类内部作为静态类):
@Singleton static class ConfigurableFixedClockProvider { @Inject @Value("${test.fixed-clock.instant:1800-10-10T00:00:00Z}") private String fixedInstant; @Bean public Clock clock() { Instant instant = Instant.parse(fixedInstant); return Clock.fixed(instant, ZoneOffset.UTC); } }
步骤2:在测试方法中指定属性
在测试类中,通过@Property注解为每个测试方法设置对应的时间属性:
@MicronautTest(rebuildContext = true) class AzureTest { @Inject Clock clock; @Test void testItWorks() { // 使用默认的1800-10-10 LocalDate date = clock.instant().atZone(ZoneOffset.UTC).toLocalDate(); assertThat(date).isEqualTo(LocalDate.of(1800, 10, 10)); } @Test @Property(name = "test.fixed-clock.instant", value = "1900-10-10T00:00:00Z") void testItWorks2() { LocalDate date = clock.instant().atZone(ZoneOffset.UTC).toLocalDate(); assertThat(date).isEqualTo(LocalDate.of(1900, 10, 10)); } }
方案二:修正@MockBean结合@Requires的方案
如果坚持使用@MockBean,需要确保每个测试方法对应的Bean被正确激活,核心是保证上下文重建时@Requires条件与测试方法的@Property匹配。
修改后的测试类代码:
@MicronautTest(rebuildContext = true) class AzureTest { @Inject Clock clock; @MockBean(Clock.class) @Requires(missingProperty = "test.clock.version") Clock fixedClock1800() { return Clock.fixed( LocalDate.of(1800, 10, 10).atStartOfDay().toInstant(ZoneOffset.UTC), ZoneOffset.UTC ); } @MockBean(Clock.class) @Requires(property = "test.clock.version", value = "1900") Clock fixedClock1900() { return Clock.fixed( LocalDate.of(1900, 10, 10).atStartOfDay().toInstant(ZoneOffset.UTC), ZoneOffset.UTC ); } @Test void testItWorks() { LocalDate date = clock.instant().atZone(ZoneOffset.UTC).toLocalDate(); assertThat(date).isEqualTo(LocalDate.of(1800, 10, 10)); } @Test @Property(name = "test.clock.version", value = "1900") void testItWorks2() { LocalDate date = clock.instant().atZone(ZoneOffset.UTC).toLocalDate(); assertThat(date).isEqualTo(LocalDate.of(1900, 10, 10)); } }
关键说明
- 必须添加
@MicronautTest(rebuildContext = true),确保每个测试方法重建独立的上下文,这样不同的@Property才能触发对应的@Requires条件,加载正确的ClockBean。 - 避免两个
@MockBean的条件出现重叠,确保每个测试场景下只有一个ClockBean被加载。
内容的提问来源于stack exchange,提问作者ajinzrathod
相关产品推荐
相关产品推荐

