5

My Service class is below, followed by its test -

@Service
public class MyServiceImpl implements MyService {

        @Autowired
        private RestTemplate restTemplate;

        @Override
        public StudentInfo getStudentInfo(String name) {
            HttpHeaders headers = new HttpHeaders();
            headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);

            HttpEntity entity = new HttpEntity(headers);

            StudentInfo student = null;

            URI uri = new URI("http:\\someurl.com");             

           ResponseEntity<String> responseEntity = restTemplate.exchange(uri,
                        HttpMethod.GET, entity,
                        String.class);

           if (responseEntity.getStatusCode().equals(HttpStatus.NO_CONTENT)) {
                   throw new Exception("Student absent");
            }else {
              ObjectMapper mapper = new ObjectMapper();
              StudentInfo student = mapper.readValue(responseEntity.getBody(), StudentInfo.class);

           }

            return student;
        }
    }

Test class: In my test class below, I see ResponseEntity object as null while debugging which causes a NPE.

@RunWith(MockitoJUnitRunner.class)
public class MyServiceImplTest {

    @InjectMocks
    private MyService service = new MyServiceImpl();

    @Mock
    private RestTemplate restTemplate;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testStudentGetterResponse() {

        ResponseEntity<String> mockEntity = Mockito.spy(new ResponseEntity({"id" : 1, "name" : "Rutzen"}, HttpStatus.OK));

        doReturn(mockEntity).when(restTemplate).exchange(any(URI.class), any(HttpMethod.class), any(ResponseEntity.class),
                any(Class.class));

        StudentInfo info = service.getStudentInfo("testuser");

        Assert.assertNotNull(info);


    }

}

When I debug the test, I get a null value for responseEntity at the following line in the main service class -

 ResponseEntity<String> responseEntity = restTemplate.exchange(uri,
                        HttpMethod.GET, entity,
                        String.class);
Plog
  • 9,164
  • 5
  • 41
  • 66
Righto
  • 855
  • 3
  • 11
  • 32

3 Answers3

9

This instruction ...

doReturn(mockEntity).when(restTemplate).exchange(
    any(URI.class), 
    any(HttpMethod.class), 
    any(ResponseEntity.class),              
    any(Class.class)
);

... should be replaced with:

doReturn(mockEntity).when(restTemplate).exchange(
    any(URI.class), 
    any(HttpMethod.class), 
    any(HttpEntity.class),              
    any(Class.class)
);

Because getStudentInfo() creates an instance of HttpEntity (not ResponseEntity) which is then passed to the restTemplate.exchange() invocation.

glytching
  • 44,936
  • 9
  • 114
  • 120
  • That did not help, same issue – Righto Aug 14 '17 at 13:16
  • Are you sure you are seeing the **same* issue? I grabbed your code and reproduced the issue and then fixed it by making the change I suggested in my answer. While doing that I noticed that I also had to tidy up a few other small items in your code (e.g. backslashes instead of forward slashes in the URI constructor). If you are now using `any(HttpEntity.class)` perhaps the error is now coming from somewhere else? – glytching Aug 14 '17 at 13:19
  • 1
    Found the issue - which is quite weird actually. When I edited the code so that responseEntity mock set up is in the same line instead of multiple lines, it starts working – Righto Aug 14 '17 at 13:32
  • @glytching thanks alot , i am finding this answer from 3 days. – Parmar Kamlesh Nov 22 '19 at 07:22
  • @Righto you should add that in the answer. Same thing happen with me and i fixed it after reading your comment. Thanks – Pirate Jul 16 '20 at 11:24
  • @glytching I have the same issue but I couldn't fix it. How can I fix it? Here is the link : https://stackoverflow.com/questions/76308882/spring-boot-junit-test-resttemplate-returns-null-in-servicetest – S.N May 22 '23 at 20:31
1

As the accepted answer is correct. I'm adding something to the already accepted answer.

It seems little bit strange but i fixed the issue by seeing the accepted answer and the comment is added by the user who raised the question.

Replace this

doReturn(mockEntity).when(restTemplate).exchange(
    any(URI.class), 
    any(HttpMethod.class), 
    any(ResponseEntity.class),              
    any(Class.class)
);

With,

doReturn(mockEntity).when(restTemplate).exchange(
    any(URI.class), 
    any(HttpMethod.class), 
    any(HttpEntity.class),              
    any(Class.class)
);

And if you are still getting the error then don't use multiple lines. Use only one line and replace it like below.

doReturn(mockEntity).when(restTemplate).exchange(any(URI.class), any(HttpMethod.class), any(HttpEntity.class), any(Class.class)
);
Pirate
  • 2,886
  • 4
  • 24
  • 42
0
 ResponseEntity<String> responseEntity = restTemplate.exchange(uri,
                        HttpMethod.GET, entity,
                        String.class);

I will not work in case of String[]

like

ResponseEntity<String[]> responseEntity = restTemplate.exchange(uri,
                        HttpMethod.GET, entity,
                        String[].class);