使用 jUnit 和 Mockito 对外部 REST API 调用进行单元测试
Unit Testing with jUnit and Mockito for External REST API calls
我正在 Spring 引导 Java 应用程序中为服务 class 构建单元测试。
服务 class 对 REST API 服务进行外部调用,return 响应 JSON。我正在使用 Mockito 模拟这个调用。我在模拟服务器响应中硬编码 JSON。
在单元测试中硬编码 JSON 是一种不好的做法吗?如果 JSON 结构改变,那么测试应该失败是我的推理。是否有更好的最佳实践在哪里执行此操作?
下面的示例代码段:
实际代码是有效的,为了简洁起见,我只是编辑了这个片段,以便理解这个想法,所以 post 如果您发现任何错误,请发表评论:
public class UserServiceTest extends TestCase {
private static final String MOCK_URL = "baseUrl";
private static final String DEFAULT_USER_ID = "353";
UserService classUnderTest;
ResponseEntity<Customer> mockResponseEntity;
MockRestServiceServer mockServer;
@Mock
RestTemplate mockRestTemplate;
public void setUp() throws Exception {
super.setUp();
classUnderTest = new UserRestService();
mockRestTemplate = new RestTemplate();
mockServer = MockRestServiceServer.createServer(mockRestTemplate);
ReflectionTestUtils.setField(classUnderTest, "restTemplate",
mockRestTemplate);
ReflectionTestUtils.setField(classUnderTest, "userSvcUrl",
MOCK_URL);
}
public void testGetUserById() throws Exception {
mockServer.expect(requestTo(MOCK_URL + "/Users/" + DEFAULT_USER_ID)).andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(
"{\n" +
" \"UserCredentials\": {\n" +
" \"Password\": \"\",\n" +
" \"PasswordNeedsUpdate\": false,\n" +
" \"Security\": [\n" +
" {\n" +
" \"Answer\": \"\",\n" +
" \"Question\": \"Why did the bicycle fall over?\"\n" +
" }\n" +
" ]\n" +
"}"
, MediaType.APPLICATION_JSON));
Customer customer = classUnderTest.getUserById(DEFAULT_USER_ID);
mockServer.verify();
assertNotNull(customer);
assertEquals(DEFAULT_USER_ID, customer.getId());
}
}
我目前和你处在同一条船上,我的推理如下:
创建一个虚拟 JSON-response 就像模拟一个对象并使用 Mockito.when
控制它一样。当您更改某些内部解析或您期望不同的结果时,您需要更改 when().thenReturn()
调用中的任何内容。这与 JSON-response 相同,其中调用已更改且对象表示已更改。
因此我猜这很好。阅读有关测试 REST API 的各种文章后,普遍认为创建虚拟 JSON 响应是一种很好的做法。最佳做法是(不时地)下载真实的 JSON-response 并将其作为模拟响应插入。通过这种方式,您可以让您的测试与外部方保持最新,而测试可以 运行 无需互联网请求。
按要求编辑:
Ruby - Stubbing external services,
Python - Testing a successful call
JavaScript - An example of AJAX testing
我想阐明另一种要考虑的方法,即创建 JSON 表示的对象的 POJO(例如数据模型、JavBean),然后使用 JSON序列化程序,例如 Google 中的 Gson,将其转换为 JSON 字符串。
UserCredentials uc = new UserCredentials ();
//set the values
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(uc);
我正在 Spring 引导 Java 应用程序中为服务 class 构建单元测试。
服务 class 对 REST API 服务进行外部调用,return 响应 JSON。我正在使用 Mockito 模拟这个调用。我在模拟服务器响应中硬编码 JSON。
在单元测试中硬编码 JSON 是一种不好的做法吗?如果 JSON 结构改变,那么测试应该失败是我的推理。是否有更好的最佳实践在哪里执行此操作?
下面的示例代码段:
实际代码是有效的,为了简洁起见,我只是编辑了这个片段,以便理解这个想法,所以 post 如果您发现任何错误,请发表评论:
public class UserServiceTest extends TestCase {
private static final String MOCK_URL = "baseUrl";
private static final String DEFAULT_USER_ID = "353";
UserService classUnderTest;
ResponseEntity<Customer> mockResponseEntity;
MockRestServiceServer mockServer;
@Mock
RestTemplate mockRestTemplate;
public void setUp() throws Exception {
super.setUp();
classUnderTest = new UserRestService();
mockRestTemplate = new RestTemplate();
mockServer = MockRestServiceServer.createServer(mockRestTemplate);
ReflectionTestUtils.setField(classUnderTest, "restTemplate",
mockRestTemplate);
ReflectionTestUtils.setField(classUnderTest, "userSvcUrl",
MOCK_URL);
}
public void testGetUserById() throws Exception {
mockServer.expect(requestTo(MOCK_URL + "/Users/" + DEFAULT_USER_ID)).andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(
"{\n" +
" \"UserCredentials\": {\n" +
" \"Password\": \"\",\n" +
" \"PasswordNeedsUpdate\": false,\n" +
" \"Security\": [\n" +
" {\n" +
" \"Answer\": \"\",\n" +
" \"Question\": \"Why did the bicycle fall over?\"\n" +
" }\n" +
" ]\n" +
"}"
, MediaType.APPLICATION_JSON));
Customer customer = classUnderTest.getUserById(DEFAULT_USER_ID);
mockServer.verify();
assertNotNull(customer);
assertEquals(DEFAULT_USER_ID, customer.getId());
}
}
我目前和你处在同一条船上,我的推理如下:
创建一个虚拟 JSON-response 就像模拟一个对象并使用 Mockito.when
控制它一样。当您更改某些内部解析或您期望不同的结果时,您需要更改 when().thenReturn()
调用中的任何内容。这与 JSON-response 相同,其中调用已更改且对象表示已更改。
因此我猜这很好。阅读有关测试 REST API 的各种文章后,普遍认为创建虚拟 JSON 响应是一种很好的做法。最佳做法是(不时地)下载真实的 JSON-response 并将其作为模拟响应插入。通过这种方式,您可以让您的测试与外部方保持最新,而测试可以 运行 无需互联网请求。
按要求编辑:
Ruby - Stubbing external services,
Python - Testing a successful call
JavaScript - An example of AJAX testing
我想阐明另一种要考虑的方法,即创建 JSON 表示的对象的 POJO(例如数据模型、JavBean),然后使用 JSON序列化程序,例如 Google 中的 Gson,将其转换为 JSON 字符串。
UserCredentials uc = new UserCredentials ();
//set the values
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(uc);