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

如何为不同测试方法使用不同的WireMock映射文件?

问题描述

我在@SpringBootTest中使用WireMock(依赖spring-cloud-contract-wiremock),当前通过代码为两个测试方法的同一请求配置不同存根,运行正常。但我想改用JSON存根文件的方式,目前只能用单个JSON文件存放存根,请问如何为两个测试方法分别配置独立的JSON文件,并指定测试方法加载对应的WireMock存根文件?

使用版本:

  • spring-boot-parent 3.1.0
  • WireMock依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-contract-wiremock</artifactId>
    <version>4.0.2</version>
    <scope>test</scope>
</dependency>

现有代码示例:

import static com.github.tomakehurst.wiremock.client.WireMock.*;

@SpringBootTest
@AutoConfigureWireMock(port = 0)
class SomeTest {

    @Test
    void test1() {
        WireMock.stubFor(get(urlPathEqualTo("/endpoint"))
                .willReturn(aResponse().withStatus(200))
        );

        // 测试逻辑
        // 断言响应状态为200
    }

    @Test
    void test2() {
        stubFor(get(urlPathEqualTo("/endpoint"))
                .willReturn(aResponse().withStatus(401))
        );

        // 测试逻辑
        // 断言响应状态为401
    }
}
解决方案

方法1:利用@WireMockTest指定独立存根目录

spring-cloud-contract-wiremock支持通过@WireMockTest注解为单个测试方法指定专属存根目录,替代类上的@AutoConfigureWireMock:

  1. 在src/test/resources下创建两个独立存根目录:

    • stubs/test1:存放test1对应的JSON存根文件(如endpoint-200.json)
    • stubs/test2:存放test2对应的JSON存根文件(如endpoint-401.json)
  2. 修改测试类,移除类上的@AutoConfigureWireMock,为每个测试方法添加@WireMockTest并指定存根路径:

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import org.springframework.cloud.contract.wiremock.WireMockTest;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SomeTest {

    @Test
    @WireMockTest(stubs = "classpath:stubs/test1", port = 0)
    void test1() {
        // WireMock自动加载stubs/test1下的JSON存根,无需代码定义
        // 测试逻辑
        // 断言响应状态为200
    }

    @Test
    @WireMockTest(stubs = "classpath:stubs/test2", port = 0)
    void test2() {
        // WireMock自动加载stubs/test2下的JSON存根
        // 测试逻辑
        // 断言响应状态为401
    }
}

方法2:手动控制存根加载与清理

若保留类上的@AutoConfigureWireMock,可在测试方法中手动加载指定存根文件,并在测试前后清理已有存根:

  1. 创建两个独立JSON存根文件:

    • src/test/resources/mappings/test1-endpoint.json:对应200状态的存根
    • src/test/resources/mappings/test2-endpoint.json:对应401状态的存根
  2. 注入WireMockServer实例,在测试方法中手动控制存根:

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import com.github.tomakehurst.wiremock.WireMockServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;

@SpringBootTest
@AutoConfigureWireMock(port = 0)
class SomeTest {

    @Autowired
    private WireMockServer wireMockServer;

    @Test
    void test1() {
        // 清理所有已有存根
        wireMockServer.resetMappings();
        // 加载指定存根文件
        wireMockServer.loadMappingsFrom("classpath:mappings/test1-endpoint.json");
        
        // 测试逻辑
        // 断言响应状态为200
    }

    @Test
    void test2() {
        wireMockServer.resetMappings();
        wireMockServer.loadMappingsFrom("classpath:mappings/test2-endpoint.json");
        
        // 测试逻辑
        // 断言响应状态为401
    }
}

方法3:结合测试生命周期注解分组管理存根

若需对多个测试方法分组管理存根,可使用@BeforeEach配合自定义标记接口实现:

  1. 创建自定义标记接口:
interface Test1Stub {}
interface Test2Stub {}
  1. 在测试类中根据标记加载对应存根:
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import com.github.tomakehurst.wiremock.WireMockServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;

@SpringBootTest
@AutoConfigureWireMock(port = 0)
class SomeTest {

    @Autowired
    private WireMockServer wireMockServer;

    @BeforeEach
    void setup(TestInfo testInfo) {
        wireMockServer.resetMappings();
        if (testInfo.getTestMethod().get().isAnnotationPresent(Test1Stub.class)) {
            wireMockServer.loadMappingsFrom("classpath:stubs/test1");
        } else if (testInfo.getTestMethod().get().isAnnotationPresent(Test2Stub.class)) {
            wireMockServer.loadMappingsFrom("classpath:stubs/test2");
        }
    }

    @Test
    @Test1Stub
    void test1() {
        // 测试逻辑
    }

    @Test
    @Test2Stub
    void test2() {
        // 测试逻辑
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:45:29