Spring Boot 接口 Mock

简介

在开发过程中,我们经常会遇到需要测试接口的情况。但是有些接口依赖于外部系统或服务,这就导致了测试的困难。为了解决这个问题,我们可以使用接口 Mock 的方式来模拟外部系统的行为,从而更方便地进行接口测试。

Spring Boot 是一个用于开发 Java 应用程序的开源框架,它可以帮助我们快速构建独立的、基于 Spring 的应用程序。在 Spring Boot 中,我们可以使用一些工具和库来进行接口 Mock,接下来我们就来详细介绍一下。

WireMock

WireMock 是一个用于模拟 HTTP 服务的库,它支持请求匹配,返回自定义响应等功能。我们可以使用 WireMock 来模拟外部系统的接口。

首先,我们需要在项目的 pom.xml 文件中引入 WireMock 的依赖:

<dependency>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock-jre8</artifactId>
    <version>2.31.0</version>
    <scope>test</scope>
</dependency>

接着,我们可以创建一个测试类来模拟外部系统的接口。假设我们要模拟一个获取用户信息的接口:

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

public class UserApiMockTest {

    private WireMockServer wireMockServer;

    @Before
    public void setup() {
        wireMockServer = new WireMockServer(8080);
        wireMockServer.start();
    }

    @After
    public void teardown() {
        wireMockServer.stop();
    }

    @Test
    public void testGetUserInfo() {
        stubFor(get(urlEqualTo("/users/1"))
                .willReturn(aResponse()
                .withHeader("Content-Type", "application/json")
                .withBody("{\"id\": 1, \"name\": \"John\"}")));

        // 执行接口调用
        // ...

        verify(getRequestedFor(urlEqualTo("/users/1")));
    }
}

在上面的代码中,我们创建了一个 WireMockServer 实例并启动了它。然后使用 stubFor 方法来设置接口的匹配规则和返回响应。在这个例子中,我们设置了当请求的 URL 是 /users/1 时,返回的响应是一个 JSON 字符串。

最后,我们使用 verify 方法来验证接口是否被调用过。

使用 WireMock 和 Spring Boot 集成

上面的例子中,我们手动启动了一个 WireMockServer 实例来模拟外部系统的接口。但是在实际开发中,我们通常会将接口 Mock 集成到 Spring Boot 应用程序中,以便更方便地进行测试。

首先,我们需要在项目的 pom.xml 文件中引入 WireMock 的 Spring Boot Starter 依赖:

<dependency>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock-spring-boot-starter</artifactId>
    <version>2.31.0</version>
    <scope>test</scope>
</dependency>

接着,我们需要创建一个 MockServer 配置类:

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;

@TestConfiguration
public class MockServerConfig {

    @Bean(initMethod = "start", destroyMethod = "stop")
    public WireMockServer mockServer() {
        WireMockServer wireMockServer = new WireMockServer();
        wireMockServer.start();
        return wireMockServer;
    }
}

在上面的代码中,我们使用 @TestConfiguration 注解将该类声明为一个配置类,并使用 @Bean 注解声明一个 WireMockServer 的 Bean。在这个例子中,我们使用默认的配置来创建 WireMockServer。

最后,我们可以使用 WireMock 的 API 来设置接口的 Mock:

@SpringBootTest(classes = {MockServerConfig.class})
public class UserApiMockTest {

    @Autowired
    private WireMockServer wireMockServer;

    @BeforeEach
    public void setup() {
        wireMockServer.resetAll();
        wireMockServer.stubFor(get(urlEqualTo("/users/1"))
                .willReturn(aResponse()
                .withHeader("Content-Type", "application/json")
                .withBody("{\"id\": 1, \"name\": \"John\"}")));
    }

    @