我正在为使用内部 REST API 执行操作的应用程序编写集成测试;所有 Java。
在 API 中,有一个调用外部 API 的 POST 方法。在测试中,我需要向我的 API 发送请求以执行操作。
问题是,我不想在运行集成测试时向外部 API 发送真实请求。
如何模拟外部 API 调用的响应?
有没有一种方法可以在我的测试中向我的 API(模拟或其他方式)发送 POST 请求,但对在 Java POST 方法中执行的外部调用使用模拟响应?
最佳答案
我按如下方式完成了这项工作:创建一个服务层,使 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);
}
希望对您有所帮助!
关于java - 如何模拟从内部 API 集成测试中调用的外部 API 的响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61683306/