How to fix the null value response of RestTemplate.exchange in a Mockito Test?
Asked Answered
T

3

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);
Toulouse answered 14/8, 2017 at 12:4 Comment(0)
D
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.

Dastardly answered 14/8, 2017 at 12:38 Comment(6)
That did not help, same issueToulouse
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?Dastardly
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 workingToulouse
@Dastardly thanks alot , i am finding this answer from 3 days.Eames
@Toulouse you should add that in the answer. Same thing happen with me and i fixed it after reading your comment. ThanksUriniferous
@Dastardly I have the same issue but I couldn't fix it. How can I fix it? Here is the link : #76309382Keyek
U
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)
);
Uriniferous answered 16/7, 2020 at 11:27 Comment(1)
The last suggestion was unbelievable. Thx...Tepid
A
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);
Auditory answered 30/1, 2018 at 10:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.