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

Spring Boot控制器集成测试:无需第三方工具自建Mock API可行吗?

不借助外部工具实现Mock API的几种方式

当然可以不用WireMock、MockServer这类外部工具,Spring生态本身就提供了多种方案来模拟外部API,下面是几种实用的实现方式:

1. 使用Spring Test自带的MockRestServiceServer

如果你的应用是用RestTemplate或者WebClient调用外部API,MockRestServiceServer是最直接的方案——它能拦截HTTP请求并返回预设响应,完全在测试进程内运行,不需要额外启动服务。

示例代码:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MyControllerIntegrationTest {

    @Autowired
    private TestWebClient webTestClient;

    @Autowired
    private WebClient.Builder webClientBuilder; // 假设应用用WebClient调用外部API
    private MockRestServiceServer mockServer;

    @BeforeEach
    void setUp() {
        // 绑定WebClient到MockServer
        mockServer = MockRestServiceServer.bindToWebClient(webClientBuilder.build()).build();
    }

    @Test
    void testMyApplicationApi() {
        // 模拟外部API的响应
        mockServer.expect(requestTo("https://external-api.com/data"))
                .andRespond(withSuccess("{\"key\":\"mock-value\"}", MediaType.APPLICATION_JSON));

        // 测试自己的控制器接口
        webTestClient
                .get()
                .uri("/my-application-api")
                .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                .exchange()
                .expectStatus().isOk()
                .expectBody()
                .jsonPath("$.externalData").isEqualTo("mock-value"); // 假设接口返回包含外部API的数据
    }
}

2. 编写测试专用的Mock控制器

直接写一个只在测试环境生效的RestController,让应用在测试时把外部API的地址指向这个本地Mock接口。

步骤:

  • 创建测试用的Mock控制器:
@RestController
@RequestMapping("/mock-external-api")
@Profile("test") // 只在test profile下加载
public class MockExternalApiController {

    @GetMapping("/data")
    public ResponseEntity<Map<String, String>> getMockData() {
        Map<String, String> mockResponse = new HashMap<>();
        mockResponse.put("key", "mock-value");
        return ResponseEntity.ok(mockResponse);
    }
}
  • 在测试配置文件application-test.yml里修改外部API地址:
external-api:
  url: http://localhost:${local.server.port}/mock-external-api
  • 测试时激活test profile:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
class MyControllerIntegrationTest {

    @Autowired
    private TestWebClient webTestClient;

    @Test
    void testMyApplicationApi() {
        webTestClient
                .get()
                .uri("/my-application-api")
                .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                .exchange()
                .expectStatus().isOk()
                .expectBody()
                .jsonPath("$.externalData").isEqualTo("mock-value");
    }
}

3. 直接Mock外部API调用的客户端类

如果你的应用把外部API调用封装在了某个客户端类里(比如ExternalApiClient),可以用@MockBean直接替换这个类,模拟它的方法返回值,完全绕开HTTP请求。

示例:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MyControllerIntegrationTest {

    @Autowired
    private TestWebClient webTestClient;

    @MockBean
    private ExternalApiClient externalApiClient; // 应用中封装外部API调用的类

    @Test
    void testMyApplicationApi() {
        // 模拟客户端方法的返回值
        when(externalApiClient.fetchData()).thenReturn("mock-value");

        webTestClient
                .get()
                .uri("/my-application-api")
                .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                .exchange()
                .expectStatus().isOk()
                .expectBody()
                .jsonPath("$.externalData").isEqualTo("mock-value");
    }
}

这三种方案各有优劣:

  • MockRestServiceServer适合需要模拟HTTP请求细节(比如请求头、参数)的场景;
  • 测试专用Mock控制器最接近真实HTTP交互,适合需要验证完整请求链路的场景;
  • Mock客户端类最简单,适合只关注业务逻辑、不需要验证HTTP层面细节的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:52:45