模拟POST HTTP请求获取空指针异常

时间:2018-10-21 12:13:36

标签: java rest unit-testing mockito

我有这种方法

public HTTPResult post(String url, String requestBody) throws Exception {
    return HTTPPostPut(url, requestBody, HttpMethod.POST);
}

public HTTPResult HTTPPostPut(String url, String requestBody,HttpMethod httpMethod) throws Exception {
    MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
    headers.add("content-type","application/json");
    HttpEntity requestEntity = new HttpEntity(requestBody,headers);

    try {
        ResponseEntity<String> response = this.restTemplate.exchange(url, httpMethod, requestEntity, String.class);
        return new HTTPResult((String) response.getBody(), response.getStatusCode().value());
    } catch (ResourceAccessException var8) {
        String responseBody = var8.getCause().getMessage();
        JSONObject obj = new JSONObject(responseBody);
        return new HTTPResult(obj.getString("responseBody"), Integer.parseInt(obj.getString("statusCode")));
    }
}

我为此创建了模拟并获得了空指针异常:

public void testPost() throws Exception{
    MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
    headers.add("content-type","application/json");
    HttpEntity requestEntity = new HttpEntity("{blbl}",headers);

    ResponseEntity<String> response = new ResponseEntity("{blbl}",  HttpStatus.OK);

    RestTemplate mockRestTemplate = mock(RestTemplate.class);

    when(mockRestTemplate.exchange(baseUrl, HttpMethod.POST, requestEntity, String.class)).thenReturn(response);

    RestAPI api = new RestAPI(mockRestTemplate);

    HTTPResult res = null;
    try {
        res = api.post(baseUrl,"{blbl}");
    } catch (IOException e) {
        e.printStackTrace();

    }

    assertEquals(res.getResponseBody(), "{blbl}");
    assertEquals(res.getStatusCode(), HttpStatus.OK.value());
}

调用时出现空指针异常

res = api.post(baseUrl,"{blbl}");

这是因为响应为空。

1 个答案:

答案 0 :(得分:0)

在安排模拟时使用参数匹配器,因为传递给模拟依赖项的实例与执行测试时传递的实例不同。

这将导致模拟返回空响应,因为预期的实例不匹配

重构测试

public void testPost() throws Exception {
    //Arrange
    String expected = "{blbl}";
    ResponseEntity<String> response = new ResponseEntity(expected,  HttpStatus.OK);    

    RestTemplate mockRestTemplate = mock(RestTemplate.class);

    when(mockRestTemplate.exchange(eq(baseUrl), eq(HttpMethod.POST), any(HttpEntity.class), eq(String.class)))
        .thenReturn(response);

    RestAPI api = new RestAPI(mockRestTemplate);

    //Act
    HTTPResult res = api.post(baseUrl, expected);

    //Assert
    assertEquals(res.getResponseBody(), expected);
    assertEquals(res.getStatusCode(), HttpStatus.OK.value());
}

请注意使用any(HttpEntity.class)匹配器,该匹配器将在调用传递的HttpEntity时对其进行匹配。

由于自变量匹配的使用为无或全部,因此eq()匹配器将用于其余的常量自变量。