【问题标题】:How to mock response of an external API called from within an internal API integration test如何模拟从内部 API 集成测试中调用的外部 API 的响应
【发布时间】:2020-08-24 06:07:48
【问题描述】:

我正在为使用内部 REST API 执行操作的应用程序编写集成测试;所有 Java。
在 API 中,有一个调用外部 API 的 POST 方法。在测试中,我需要向我的 API 发送请求以执行操作。
问题是,我不想在运行集成测试时向外部 API 发送真正的请求。
如何模拟外部 API 调用的响应?
有没有办法我仍然可以在我的测试中向我的 API(模拟或其他方式)发送 POST 请求,但对在 Java POST 方法中执行的外部调用使用模拟响应?

【问题讨论】:

  • 您可以使用 Wiremock。它启动一个 http 服务器,您可以使用请求/响应进行配置。
  • @daniu 我在我的用例中找不到任何资源。我是否只需向我的内部 API 发送一个普通的 http POST 请求,并使用 Wiremock 存根发送到外部 API 的请求?
  • 是的,将外部调用配置为转到 Wiremock 地址并设置预期响应。

标签: java api testing mockito integration


【解决方案1】:

我已按如下方式完成此操作:创建一个服务层,使 API 调用外部服务。我在 Spring 的 RestTemplate 上构建了我的,但您可以使用任何库进行调用。所以它会有 get() 或 post() 之类的方法。

然后我使用 Postman 对外部 API 执行一些请求,并将响应保存在文件中,并将这些文件添加到我的项目中。

最后,在我的测试中,我模拟了对我的小 API 服务层的调用,这样它就不会转到外部 API,而是从我之前保存的测试文件中读取。这将使用来自外部 API 的已知有效负载运行被测代码,但在测试期间不需要连接到它,并且在我自己更新文件中的响应之前不会改变。

我使用 EasyMock,但任何模拟库都可以使用。下面是一个测试的例子。

    @Test
    public void test_addPhoneToExternalService() {
        // Mock my real API service.
        ApiService mockApiService = EasyMock.createMock(ApiService.class);
        // Construct my service under test using my mock instead of the real one.
        ServiceUnderTest serviceUnderTest = new ServiceUnderTest(mockApiService);
        // Expect the body of the POST request to look like this.
        Map<String, Object> requestBody = new HashMap<String, Object>() {{
            put("lists", 0);
            put("phone", "800-555-1212");
            put("firstName", "firstName");
            put("lastName", "lastName");
        }};
        // Read the response that I manually saved as json.
        JsonNode expectedResponse = Utils.readJson("response.json");
        expect(mockApiService.post(anyObject(),
                eq("https://rest.someservice.com/api/contacts"), eq(serialize(requestBody))))
                .andReturn(expectedResponse);
        EasyMock.replay(mockApiService);
        // Call the code under test. It ingests the response 
        // provided by the API service, which is now mocked, 
        // and performs some operations, then returns a value 
        // based on what the response contained (for example, 
        // "{\"id\":42}").
        long id = serviceUnderTest.addPhone("firstName", "lastName", "800-555-1212");
        Assert.assertThat(id, is(42L));
        EasyMock.verify(mockApiService);
    }

希望有帮助!

【讨论】:

    猜你喜欢
    • 2015-03-20
    • 1970-01-01
    • 2016-07-19
    • 2022-01-24
    • 2016-06-01
    • 2019-03-10
    • 2016-07-27
    • 2016-03-06
    • 2021-10-30
    相关资源
    最近更新 更多