使用jUnit和Mockito进行外部REST API调用的单元测试

ana*_*ocs 7 java junit spring unit-testing mockito

我正在Spring Boot Java应用程序中为服务类构建单元测试.

服务类对返回JSON响应的REST API服务进行外部调用.我正在用Mockito嘲笑这个电话.我在mockserver响应中硬编码JSON.

这是一种不好的做法,在单元测试中使用硬编码的JSON吗?如果JSON结构发生变化,那么测试失败就是我的推理.有没有更好的,最好的做法在哪里这样做?

下面的示例代码段:

实际的代码是实用的,我只是编辑了这个片段,为了简洁起见,所以如果您发现任何错误,请发表评论:

    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());
    }
}
Run Code Online (Sandbox Code Playgroud)

Tim*_*ppe 7

我目前与你在同一条船上,我的推理如下:创建一个虚拟JSON响应就像模拟一个对象并使用它来控制它Mockito.when.when().thenReturn()当您更改了一些内部解析或者期望不同的结果时,您需要更改调用中的任何内容.这与JSON响应相同,其中调用被更改并且对象表示被更改.

因此,我的猜测是这很好.阅读有关测试REST API的各种文章,一般的共识是创建虚拟JSON响应是一种很好的做法.最佳做法是(不时)下载真正的JSON响应并将其作为模拟响应插入.这样,您可以使测试与外部方保持同步,而测试可以在没有互联网请求的情况下运行.

按要求编辑:


Jos*_*nez 5

我想介绍另一种可以考虑的方法,那就是创建 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);
Run Code Online (Sandbox Code Playgroud)