You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一类中为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条件,加载正确的Clock Bean。
  • 避免两个@MockBean的条件出现重叠,确保每个测试场景下只有一个Clock Bean被加载。

内容的提问来源于stack exchange,提问作者ajinzrathod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 22:34:53