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

本地开发时如何在Micronaut中启动WireMock拦截外部服务调用

Micronaut 本地开发自动集成WireMock实现方案

Micronaut 原生提供和Spring Profile对等的环境隔离能力,本地开发启动时默认激活dev环境,你完全可以参照之前Spring里的dev环境专属配置思路实现WireMock自动启停,不需要侵入生产代码,具体步骤如下:

1. 添加开发期WireMock依赖

将WireMock标记为仅开发阶段生效的依赖,不会被打包进生产部署产物:

  • 若使用Gradle(Groovy DSL),在build.gradle中添加:
developmentOnly "com.github.tomakehurst:wiremock-jre8-standalone:2.35.1"
  • 若使用Maven,在pom.xml中添加:
<dependency>
  <groupId>com.github.tomakehurst</groupId>
  <artifactId>wiremock-jre8-standalone</artifactId>
  <version>2.35.1</version>
  <scope>development</scope>
</dependency>

2. 编写dev环境专属的WireMock生命周期配置

创建一个仅在dev环境下才会被Micronaut上下文加载的配置类,绑定应用生命周期自动启停WireMock:

import com.github.tomakehurst.wiremock.WireMockServer;
import io.micronaut.context.annotation.Context;
import io.micronaut.context.annotation.Requires;
import io.micronaut.context.event.ShutdownEvent;
import io.micronaut.context.event.StartupEvent;
import io.micronaut.runtime.event.annotation.EventListener;
import jakarta.inject.Singleton;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;

// 核心注解:仅当dev环境激活时才加载当前类
@Requires(env = "dev")
@Singleton
@Context // 应用启动时立即初始化当前Bean,不需要等其他Bean注入触发
public class DevWireMockConfig {

    private WireMockServer wireMockServer;
    // 固定WireMock监听端口,避免每次启动端口变动需要改配置
    private static final int WIRE_MOCK_PORT = 9999;

    @EventListener
    public void onAppStartup(StartupEvent event) {
        wireMockServer = new WireMockServer(wireMockConfig().port(WIRE_MOCK_PORT));
        wireMockServer.start();
        // 加载预设的接口模拟规则
        loadMockStubs();
    }

    private void loadMockStubs() {
        // 示例:拦截外部用户服务的查询请求,返回预设模拟响应
        stubFor(get(urlPathEqualTo("/api/external/users/1"))
                .willReturn(okJson("""
                    {
                        "id": 1,
                        "username": "mock_user",
                        "email": "mock@local.dev"
                    }
                """))
        );
        // 其他外部服务的模拟规则按相同格式追加即可
    }

    @EventListener
    public void onAppShutdown(ShutdownEvent event) {
        if (wireMockServer != null && wireMockServer.isRunning()) {
            wireMockServer.stop();
        }
    }
}

3. 配置dev环境下的外部服务指向

在src/main/resources/application-dev.yml中配置所有外部服务的调用地址为本地WireMock地址,这个配置文件仅在dev环境激活时会被加载,完全不会影响其他环境:

micronaut:
  http:
    services:
      # 对应你代码中@Client("user-service")声明的外部服务客户端
      user-service:
        urls:
          - http://localhost:9999
      # 其他需要被WireMock拦截的外部服务都可以指向同一个端口
      order-service:
        urls:
          - http://localhost:9999

可选优化项

  • 如果模拟规则较多,可以把WireMock原生支持的JSON格式stub文件放到src/main/resources/wiremock/mappings目录下,启动WireMock时直接加载目录内所有规则,不用把stub逻辑硬编码在Java代码中,初始化代码修改为:
wireMockServer = new WireMockServer(wireMockConfig()
        .port(WIRE_MOCK_PORT)
        .usingFilesUnderClasspath("wiremock")
);
  • 如果不想固定端口,可以配置WireMock启动时选择随机可用端口,再通过Micronaut的动态属性注入机制把随机端口写入服务地址配置,不过本地开发场景下固定端口调试成本更低。

注意:不要把上述WireMock配置类放到测试代码目录,要保留在main源码路径下,靠@Requires(env = "dev")注解控制加载范围,这样不管是直接在IDE里运行主启动类,还是用./gradlew run/mvn mn:run命令启动应用,都会自动拉起WireMock,生产环境部署时不会激活dev环境,相关代码和依赖都不会生效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:36:23