mcpField
U
unit-test-wiremock-rest-api

unit-test-wiremock-rest-api

github.com/giuseppe-trisciuoglio测试与质量3653.8k 次安装7 周前更新
代码仓库

关于 unit-test-wiremock-rest-api

面向测试外部 REST API 集成的 WireMock 技能指南,介绍如何隔离网络依赖并验证客户端行为。涵盖响应桩、请求校验及超时和错误场景。

主要功能

  1. 01使用 WireMock 模拟 HTTP 响应
  2. 02匹配 URL、请求头和请求体
  3. 03验证客户端发出的请求
  4. 04覆盖超时与错误响应
  5. 05使用动态端口避免冲突

适用场景

  1. 01测试调用第三方 REST API 的服务
  2. 02模拟 4xx、5xx 和超时情况
  3. 03校验请求参数、请求头及请求体
  4. 04并行运行隔离网络的测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill unit-test-wiremock-rest-api

安装后在 Claude Code 中输入/unit-test-wiremock-rest-api确认已加载。

附带文件references/advanced-examples.md

详细介绍

使用 WireMock 测试 REST API

概述

使用 WireMock 测试外部 REST API 集成的模式:桩响应、验证请求、测试错误场景,以及无需网络依赖的快速测试。

适用场景

  • 测试调用外部 REST API 的服务
  • 为 HTTP 响应设置桩,以便获得可预测的测试行为
  • 测试错误场景(超时、5xx 错误、格式错误的响应)
  • 验证请求详情(标头、查询参数、请求正文)

操作说明

  1. 添加依赖项:在测试作用域中添加 WireMock(Maven/Gradle)
  2. 注册扩展:使用 @RegisterExtension WireMockExtension 和 dynamicPort()
  3. 配置客户端:使用 wireMock.getRuntimeInfo().getHttpBaseUrl() 作为基础 URL
  4. 设置响应桩:使用 stubFor() 并匹配请求(URL、标头、正文)
  5. 执行并断言:调用服务方法,使用 AssertJ 验证结果
  6. 验证请求:使用 verify() 确保 API 使用正确

如果桩未匹配:检查 URL 编码和标头名称;查询参数使用 urlEqualTo。

如果测试挂起:在 HTTP 客户端中配置连接超时;使用 withFixedDelay() 模拟超时。

如果端口冲突:始终使用 wireMockConfig().dynamicPort()。

示例

Maven 依赖项
<dependency>
  <groupId>org.wiremock</groupId>
  <artifactId>wiremock</artifactId>
  <version>3.4.1</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.assertj</groupId>
  <artifactId>assertj-core</artifactId>
  <scope>test</scope>
</dependency>
基本桩设置与验证
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.assertj.core.api.Assertions.assertThat;

class ExternalWeatherServiceTest {

  @RegisterExtension
  static WireMockExtension wireMock = WireMockExtension.newInstance()
    .options(wireMockConfig().dynamicPort())
    .build();

  @Test
  void shouldFetchWeatherDataFromExternalApi() {
    wireMock.stubFor(get(urlEqualTo("/weather?city=London"))
      .withHeader("Accept", containing("application/json"))
      .willReturn(aResponse()
        .withStatus(200)
        .withHeader("Content-Type", "application/json")
        .withBody("{\"city\":\"London\",\"temperature\":15,\"condition\":\"Cloudy\"}")));

    String baseUrl = wireMock.getRuntimeInfo().getHttpBaseUrl();
    WeatherApiClient client = new WeatherApiClient(baseUrl);
    WeatherData weather = client.getWeather("London");

    assertThat(weather.getCity()).isEqualTo("London");
    assertThat(weather.getTemperature()).isEqualTo(15);

    wireMock.verify(getRequestedFor(urlEqualTo("/weather?city=London"))
      .withHeader("Accept", containing("application/json")));
  }
}

错误场景、正文验证、超时模拟和有状态测试请参见 references/advanced-examples.md。

最佳实践

  • 动态端口:避免并行执行测试时发生冲突
  • 验证请求:确保客户端正确使用 API
  • 测试错误:覆盖超时、4xx 和 5xx 场景
  • 专注的桩:每个测试只关注一个问题
  • 自动重置:@RegisterExtension 会在测试之间重置 WireMock
  • 切勿调用真实 API:始终为第三方端点设置桩

限制和警告

  • 必须使用动态端口:固定端口会导致并行执行冲突
  • HTTPS 测试:测试 TLS 连接时配置 WireMock TLS 设置
  • 桩优先级:更具体的桩优先于通用桩
  • 性能:WireMock 会增加开销;在客户端层进行模拟可加快测试
  • API 变更:确保桩与实际 API 契约保持同步

参考资料

评论

支持 Markdown