如何模拟从内部API集成测试中调用的外部API的响应



我正在为一个使用内部REST API执行操作的应用程序编写集成测试;所有Java
在API中,有一个POST方法调用外部API。在测试中,我需要向我的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);
}

希望能有所帮助!

最新更新