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

如何为WireMock TestContainer动态配置Stubbing等功能?

WireMock TestContainer 动态配置 Stubbing 方法

要实现WireMock TestContainer的动态Stub配置,核心是获取运行中容器的WireMock客户端实例,在测试执行的任意阶段调用stubFor()等API,无需在容器启动前静态定义。以下是具体实现方案(以Java为主,附Python示例):

1. 依赖准备(Java)

确保引入TestContainers的WireMock模块,Maven或Gradle配置如下:

<!-- Maven -->
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>wiremock</artifactId>
    <scope>test</scope>
</dependency>
// Gradle
testImplementation 'org.testcontainers:wiremock'

2. Java 动态配置示例(JUnit 5)

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.AfterEach;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import com.github.tomakehurst.wiremock.WireMock;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

@Testcontainers
public class DynamicWireMockTest {

    // 初始化WireMock容器,不预先配置任何Stub
    @Container
    private final WireMockContainer wiremockContainer = new WireMockContainer("wiremock/wiremock:3.3.1");

    private WireMock wireMock;

    // 测试前获取客户端实例
    @org.junit.jupiter.api.BeforeEach
    void setUp() {
        wireMock = wiremockContainer.getWireMock();
    }

    // 测试后重置Stub,保证测试隔离
    @AfterEach
    void tearDown() {
        wireMock.resetAllMappings();
    }

    @Test
    void testDynamicStubUpdates() throws Exception {
        // 动态添加第一个Stub
        wireMock.stubFor(get(urlEqualTo("/user/profile"))
                .willReturn(aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "application/json")
                        .withBody("{\"name\": \"Initial User\"}")));

        // 验证请求结果
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(wiremockContainer.getEndpoint().resolve("/user/profile"))
                .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        assertEquals("{\"name\": \"Initial User\"}", response.body());

        // 动态替换Stub
        wireMock.stubFor(get(urlEqualTo("/user/profile"))
                .willReturn(aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "application/json")
                        .withBody("{\"name\": \"Updated User\"}")));

        // 验证更新后的响应
        HttpResponse<String> updatedResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
        assertEquals("{\"name\": \"Updated User\"}", updatedResponse.body());

        // 动态删除指定Stub
        wireMock.removeStub(get(urlEqualTo("/user/profile")));
    }
}

关键说明

  • wiremockContainer.getWireMock():返回连接到运行中容器的WireMock客户端,所有stubFor()、removeStub()调用都会实时生效
  • 可在测试方法内、@BeforeEach/@AfterEach钩子,甚至测试执行的条件分支中动态调整Stub
  • 调用resetAllMappings()可清空所有Stub,保证不同测试用例的隔离性

3. Python 动态配置示例

使用testcontainers-wiremock库,通过WireMock的管理API实现动态配置:

from testcontainers.wiremock import WireMockContainer
import requests

def test_dynamic_wiremock_stub():
    with WireMockContainer("wiremock/wiremock:3.3.1") as container:
        wiremock_base_url = container.get_url()
        
        # 动态添加Stub
        stub_payload = {
            "request": {"method": "POST", "url": "/api/orders"},
            "response": {"status": 201, "body": "{\"orderId\": \"12345\"}"}
        }
        requests.post(f"{wiremock_base_url}/__admin/mappings", json=stub_payload)
        
        # 验证请求
        response = requests.post(f"{wiremock_base_url}/api/orders")
        assert response.json()["orderId"] == "12345"
        
        # 动态更新Stub
        updated_payload = {
            "request": {"method": "POST", "url": "/api/orders"},
            "response": {"status": 201, "body": "{\"orderId\": \"67890\"}"}
        }
        # 先删除旧Stub,再添加新的(或直接PUT更新)
        requests.delete(f"{wiremock_base_url}/__admin/mappings")
        requests.post(f"{wiremock_base_url}/__admin/mappings", json=updated_payload)
        
        updated_response = requests.post(f"{wiremock_base_url}/api/orders")
        assert updated_response.json()["orderId"] == "67890"

注意事项

  • 保持WireMock容器镜像版本与客户端API兼容,避免因版本差异导致的调用失败
  • 若需跨测试方法共享基础Stub,可在全局初始化逻辑中配置,测试方法内按需修改
  • 复杂场景下可使用wireMock.register(MappingBuilder)或管理API批量配置Stub

内容的提问来源于stack exchange,提问作者Martin Schröder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:40:21