如何在Spring的单元测试中模拟远程REST API?

2022-09-01 00:36:54

假设我已经在我的应用程序中创建了一个简单的客户端,该客户端使用远程Web服务,该服务在某些URI处公开了RESTful API。现在,我希望对调用此 Web 服务的客户端进行单元测试。/foo/bar/{baz}

理想情况下,在我的测试中,我想模拟我从Web服务获得的响应,给定一个特定的请求,如或。我的客户端假设API实际上正在某个地方运行,所以我需要一个本地的“Web服务”来开始运行我的测试。/foo/bar/123/foo/bar/42http://localhost:9090/foo/bar

我希望我的单元测试是独立的,类似于使用Spring MVC测试框架测试Spring控制器。

一些简单客户端的伪代码,从远程API获取数字:

// Initialization logic involving setting up mocking of remote API at 
// http://localhost:9090/foo/bar

@Autowired
NumberClient numberClient // calls the API at http://localhost:9090/foo/bar

@Test
public void getNumber42() {
    onRequest(mockAPI.get("/foo/bar/42")).thenRespond("{ \"number\" : 42 }");
    assertEquals(42, numberClient.getNumber(42));
}

// ..

使用Spring有哪些替代方案?


答案 1

如果你使用弹簧,你可以使用.一个示例可以在这里找到 使用MockRestServiceServer进行REST客户端测试RestTemplateMockRestServiceServer


答案 2

最好的方法是使用WireMock。添加以下依赖项:

    <dependency>
        <groupId>com.github.tomakehurst</groupId>
        <artifactId>wiremock</artifactId>
        <version>2.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.igniterealtime.smack</groupId>
        <artifactId>smack-core</artifactId>
        <version>4.0.6</version>
    </dependency>

定义和使用线轴,如下所示

@Rule
public WireMockRule wireMockRule = new WireMockRule(8089);

String response ="Hello world";
StubMapping responseValid = stubFor(get(urlEqualTo(url)).withHeader("Content-Type", equalTo("application/json"))
            .willReturn(aResponse().withStatus(200)
                    .withHeader("Content-Type", "application/json").withBody(response)));

推荐