Search code examples
javaspringspring-bootjunitresttemplate

RestTemplate Junit: Cannot invoke "org.springframework.http.ResponseEntity.getBody()" because "response" is null


I have a spring boot application that makes an API hit of other internal projects using the rest template which works fine and I am writing unit test cases for it but test case if failing due to Unexpected exception thrown: java.lang.NullPointerException: Cannot invoke "org.springframework.http.ResponseEntity.getBody()" because "response" is null

Service

@Service
@Slf4j
public class DynamoDBServiceImpl implements DynamoDBService {

  private final RestTemplate restTemplate;
  private final HttpHeaders httpHeaders;
  private final String jwtHeader;
  private final String apiKeyHeader;
  private final String dynamodbSysApiKey;
  private final String fetchAdminGroupUrl;

  public DynamoDBServiceImpl(
      RestTemplate restTemplate,
      HttpHeaders httpHeaders,
      @Value("${header-name.jwt}") String jwtHeader,
      @Value("${header-name.api-key}") String apiKeyHeader,
      @Value("${dynamodb-sys-api-key}") String dynamodbSysApiKey,
      @Value("${dynamodb-fetch-admin-group-url}") String fetchAdminGroupUrl) {
    this.restTemplate = restTemplate;
    this.httpHeaders = httpHeaders;
    this.jwtHeader = jwtHeader;
    this.apiKeyHeader = apiKeyHeader;
    this.dynamodbSysApiKey = dynamodbSysApiKey;
    this.fetchAdminGroupUrl = fetchAdminGroupUrl;
  }

  @Override
  public List<AdminGroupDTO> getAllAdminGroups() {
    log.debug("Request to get admin group details with url : {}", fetchAdminGroupUrl);
    httpHeaders.set("Accept", MediaType.APPLICATION_JSON_VALUE);
    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
    httpHeaders.setBearerAuth(CommonUtils.getHeaderFromCurrentHttpRequest(jwtHeader));
    httpHeaders.set(apiKeyHeader, dynamodbSysApiKey);

    HttpEntity<AdminGroupDTO> request = new HttpEntity<>(httpHeaders);
    ResponseEntity<List<AdminGroupDTO>> response =
        restTemplate.exchange(fetchAdminGroupUrl, HttpMethod.GET, request, new ParameterizedTypeReference<List<AdminGroupDTO>>() {});
    return response.getBody();
  }

}

Test

@SpringBootTest(classes = Application.class)
public class DynamoDBServiceTest {

  private final RestTemplate restTemplate = Mockito.mock(RestTemplate.class);
  private final HttpHeaders httpHeaders = new HttpHeaders();
  private final DynamoDBServiceImpl dynamoDBService =
      new DynamoDBServiceImpl(
          restTemplate, httpHeaders, "Authorization" , "Api-Key", "fake", "https://fake.com");

  @Test
  void testGetAllAdminGroups() {
    List<AdminGroupDTO> adminGroupDTOList = new ArrayList<>();
    AdminGroupDTO adminGroupDTO = new AdminGroupDTO();
    adminGroupDTO.setAdminGroupId(1L);
    adminGroupDTO.setAdminGroupName("fake");
    adminGroupDTO.setCountryName("fake");
    adminGroupDTOList.add(adminGroupDTO);

    ResponseEntity<List<AdminGroupDTO>> responseEntity = new ResponseEntity<>(adminGroupDTOList, HttpStatus.OK);
    when(restTemplate.exchange(
        ArgumentMatchers.anyString(),
        ArgumentMatchers.any(HttpMethod.class),
        ArgumentMatchers.any(),
        ArgumentMatchers.<Class<List<AdminGroupDTO>>>any()))
        .thenReturn(responseEntity);

    assertDoesNotThrow(dynamoDBService::getAllAdminGroups);
  }

}

Solution

  • Replace this line of code :

     when(restTemplate.exchange(
            ArgumentMatchers.anyString(),
            ArgumentMatchers.any(HttpMethod.class),
            ArgumentMatchers.any(),
            ArgumentMatchers.<Class<List<AdminGroupDTO>>>any()))
            .thenReturn(responseEntity);
    

    With this :

    when(restTemplate.exchange(
                ArgumentMatchers.anyString(),
                ArgumentMatchers.any(HttpMethod.class),
                ArgumentMatchers.any(),
                ArgumentMatchers.eq(new ParameterizedTypeReference<List<AdminGroupDTO>>() {}))
        )
                .thenReturn(responseEntity);
    

    And excepption should dissapear.

    For futher details you can check this post.