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

如何在Micronaut中Mock用于ServerStartupEvent的客户端接口适配测试场景

解决方案

一、启动阶段全局Mock @Client 接口

你出现Mock仅在@Test方法生效的核心原因是用了JUnit的@Mock注解,该注解仅初始化测试类实例的属性,不会替换Micronaut应用上下文中的Bean实例。改用Micronaut提供的@MockBean注解即可在应用上下文初始化阶段就完成Bean替换,启动触发的ServerStartupEvent监听器注入的就是你的Mock实例:

  1. 测试类示例代码:
import io.micronaut.test.annotation.MockBean;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@MicronautTest
public class MyAppTest {

    // 替换上下文中原生的@Client生成的Bean
    @MockBean(RemoteApiClient.class)
    RemoteApiClient mockRemoteClient() {
        RemoteApiClient mock = mock(RemoteApiClient.class);
        // 提前打桩,设置启动阶段要返回的预设值
        when(mock.fetchTargetData()).thenReturn("测试预设返回值");
        return mock;
    }

    @Test
    void yourTestLogic() {
        // 此处和启动阶段的监听器拿到的都是上面的Mock实例,不会发起真实请求
    }
}

注:RemoteApiClient替换为你自己定义的被@Client注解标记的接口名,fetchTargetData替换为你调用的拉取数据方法名。

二、重写/控制OnApplicationEvent方法的方案

有两种无侵入的可选方案,按需选择:

  • 方案1:生产代码加环境条件控制(无测试代码侵入)
    给你的ServerStartupEvent监听器类加上@Requires注解,仅在非测试环境注册:
import io.micronaut.context.annotation.Requires;
import io.micronaut.runtime.server.event.ServerStartupEvent;
import io.micronaut.context.event.ApplicationEventListener;
import jakarta.inject.Singleton;

@Singleton
@Requires(notEnv = "test") // 测试环境不注册该监听器
public class StartupDataLoader implements ApplicationEventListener<ServerStartupEvent> {
    // 原有逻辑不变
}

如果测试环境需要自定义启动逻辑,可以单独写一个测试专属的监听器,加上@Requires(env = "test")注解,实现自定义的启动逻辑即可。

  • 方案2:测试代码替换原始监听器(不改动生产代码)
    在测试代码中新增一个替换类,用@Replaces注解直接替换生产环境的监听器实例,自定义执行逻辑:
import io.micronaut.context.annotation.Replaces;
import io.micronaut.runtime.server.event.ServerStartupEvent;
import io.micronaut.context.event.ApplicationEventListener;
import jakarta.inject.Singleton;

@Singleton
@Replaces(StartupDataLoader.class) // 替换生产环境的监听器
public class MockStartupDataLoader implements ApplicationEventListener<ServerStartupEvent> {
    @Override
    public void onApplicationEvent(ServerStartupEvent event) {
        // 自定义测试环境的启动逻辑,比如跳过远程调用,直接写预设数据到缓存/数据库
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 18:42:02