Issue
I have looked at multiple posts here - one for example and tried multiple variations but still can't seem to be able to get a non-null value after mocking
/>
RestTemplate#exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)
.
I am not passing any uriVariables
.
Here is my simplified source code:
Request request = new Request();
request.setDataId(1);
String query = "query ($ request:Request!)\n" +
"{\n" +
" fetchData(request:$request)\n" +
" {\n" +
" planId\n" +
" }\n" +
" }\n";
RequestBody requestBody = new RequestBody(query,Collections.singletonMap("request",
request));
HttpEntity<RequestBody> request = new HttpEntity<>(requestBody, createHttpHeaders());
return restTemplate.exchange("http://localhost:8080/gql", HttpMethod.POST, request,
JsonNode.class);
private HttpHeaders createHttpHeaders()
{
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
return headers;
}
The RequestBody
class (uses lombok
):
@Getter
@AllArgsConstructor
public class RequestBody implements Serializable {
private static final long serialVersionUID = -203524485553511477L;
private String query;
private Map<String,Object> variables;
}
And the corresponding test code:
@Mock
private RestTemplate restTemplate;
@Mock
private ObjectMapper objectMapper;
@InjectMocks
private FetchDataService fetchDataService;
@Test
public void testFetchData() {
String json = new String(Files.readAllBytes(Paths.get("src/test/resources/Data.json")));
ObjectMapper testMapper = new ObjectMapper();
JsonNode expectedResponse = testMapper.readTree(json);
when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class),
any(Class.class)))
.thenReturn(new ResponseEntity<>(expectedResponse, HttpStatus.OK));
ResponseEntity<JsonNode> response = fetchDataService.getData();
}
expectedResponse
is a JsonNode
instance above. The problem is that response
always returns a null
body.
I am able to verify that the call does happen if I use this -
Mockito.verify(restTemplate)
.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class));
I'm using junit 5, spring boot 2.6.7, jdk 11 if that matters.
Solution
As the author @linuxNoob has confirmed in our discussion in the comments, the issue was that expectedResponse
didn't hold a proper JsonNode
value. The reason for that is the ObjectMapper
instance being mocked without any configuration to return something from its methods. So, any call was returning the default null
value, i.e. testMapper.readTree(json)
returns null
that ends up being the value of the ResponseEntity.body
through the expectedResponse
.
Answered By - Dmitry Khamitov
Answer Checked By - Robin (JavaFixing Admin)