Search code examples
unit-testingjunitmockitoinvocationtargetexception

Unit test mock for RestTemplate


I have a service method with restTemplate. As part of unit test, I am trying to mock it but some how failing.

Service Method:

@Autowired
private RestTemplate getRestTemplate;

return getRestTemplate.getForObject(restDiagnosisGetUrl, SfdcCustomerResponseType.class);

Test Method:

private CaresToSfdcResponseConverter caresToSfdcResponseConverter;

    @Before
    public void setUp() throws Exception {
        caresToSfdcResponseConverter = new CaresToSfdcResponseConverter();

    }
    @Test
    public void testConvert(){
    RestTemplate mock = Mockito.mock(RestTemplate.class);
         Mockito.when(mock.getForObject(Matchers.anyString(), Matchers.eq(SfdcCustomerResponseType.class))).thenReturn(sfdcCustomerResponseType);
}
sfdcRequest = caresToSfdcResponseConverter.convert(responseForSfdcAndHybris);

It is giving NullPointerException. Looks like it is failing to mock rest template and it is breaking there as rest template is null. Any help would appreciated.Thanks


Solution

  • It's not failing to mock the rest template, but it's not injecting the mocked rest template to your production class. There are at least two ways to fix this.

    You can change your production code and use constructor injection. Move the RestTemplate to the constructor as a parameter and then you can just pass the mock in the test:

    @Service
    public class MyService {
        @Autowired
        public MyService(RestTemplate restTemplate) {
            this.restTemplate = restTemplate;
        }
    }
    

    In your test you will simply create the service as any other object and pass it your mocked rest template.

    Or you can change your test to inject your service using the following annotation:

    @RunWith(MockitoJUnitRunner.class)
    public class MyServiceTest {
        @InjectMocks
        private MyService myService;
    
        @Mock
        private RestTemplate restTemplate;
    
        @Test
        public void testConvert(){
             Mockito.when(mock.getForObject(Matchers.anyString(), Matchers.eq(SfdcCustomerResponseType.class))).thenReturn(sfdcCustomerResponseType);
        }
    }
    

    You can see an example in another SO question: Using @Mock and @InjectMocks

    I generally prefer constructor injection.