Mocking RestTemplate postforEntity

Viewed 739

I have a service class which looks like -

class A {
   @Autowired
   RestTemplate restTemplate;
   public void method() {
       res = restTemplate.postForEntity("http://abc", entity, Employee.class);
       resBody = res.getBody();      
   }
}

Following is the Test Class for it-

class TestA {
   @Mock
   RestTemplate restTemplate;
   @InjectMocks
   A obj;
   void testMethod1() {
       res = ....
       when(restTemplate.postForEntity(any(), any(), any()).thenReturn(res);
   }
   void testMethod2() {
       res = ....
       when(restTemplate.postForEntity(anyString(), any(), any()).thenReturn(res);
   }
}

testMethod1 fails throwing NullPointerException on "res.getBody() from A.method()" while testMethod2 runs successfully

Why is any() not working here while anyString() works? I thought any() works for any data type.

2 Answers

Take a look into the Javadocs for RestTemplate. There are three postForEntity methods:

  • postForEntity(String url, Object request, Class<T> responseType, Map<String,?> uriVariables)
  • postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
  • postForEntity(URI url, Object request, Class<T> responseType)

Your mock in testMethod2 catches for sure one of the first both methods. However the mock in your testMethod1 seems to cover the method with an URI as first parameter and well, therefore your restTemplate.postForEntity("http://abc", entity, Employee.class) does not match.

If you are interested in what method is currently mocked, just type a line, e. g. restTemplate.postForEntity(any(), any(), any()) and then just hover over the method in your favourite IDE to see already at compile time, which exact (overridden) method was covered.

My problem was similar, casting null to String worked for me: when(restTemplateMock.postForEntity((String)isNull(), any(), eq(List.class))) .thenReturn(responseEntityMock);

Related