I'm testing a service layer and not sure how to mock ObjectMapper().readValue
in that class. I'm fairly new to mockito
and could figure out how to do it.
The following is my code,
private configDetail fetchConfigDetail(String configId) throws IOException {
final String response = restTemplate.getForObject(config.getUrl(), String.class);
return new ObjectMapper().readValue(response, ConfigDetail.class);
}
@Test
public void testgetConfigDetailReturnsNull() throws Exception {
restTemplate = Mockito.mock(restTemplate.class);
Service service = new Service();
Config config = Mockito.mock(Config.class);
ObjectMapper objMapper = Mockito.mock(ObjectMapper.class);
Mockito.doReturn("").when(restTemplate).getForObject(anyString(), eq(String.class));
Mockito.doReturn(configDetail).when(objMapper).readValue(anyString(),eq(ConfigDetail.class));
assertEquals(configDetail, service.getConfigDetail("1234"));
}
I get the following results when I run this test,
com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input
at [Source: (String)""; line: 1, column: 0]
Posting ServiceTest.Java here
@RunWith(MockitoJUnitRunner.class)
public class ConfigServiceTest {
@Mock
private ConfigPersistenceService persistenceService;
@InjectMocks
private ConfigService configService;
@Mock
ConfigDetail configDetail;
@Mock
private RestTemplate restTemplate;
@Mock
private ObjectMapper objMapper;
@Mock
private Config config;
@Test
public void testgetConfigDetailReturnsNull() throws Exception {
ObjectMapper objMapper = Mockito.mock(ObjectMapper.class);
Mockito.doReturn(ucpConfig).when(persistenceService).findById("1234");
Mockito.doReturn("").when(restTemplate).getForObject(anyString(), eq(String.class));
Mockito.when((objMapper).readValue(“”,ConfigDetail.class)).thenReturn(configDetail);
assertEquals(ConfigDetail, ConfigService.getConfigDetail("1234"));
}
}
With your current Service class it would be difficult to mock ObjectMapper
, ObjectMapper
is tightly coupled to fetchConfigDetail
method.
You have to change your service class as follows to mock ObjectMapper
.
@Service
public class MyServiceImpl {
@Autowired
private ObjectMapper objectMapper;
private configDetail fetchConfigDetail(String configId) throws IOException {
final String response = restTemplate.getForObject(config.getUrl(), String.class);
return objectMapper.readValue(response, ConfigDetail.class);
}
}
Here what I did is instead of creating objectMapper
inside the method I am injecting that from outside (objectMapper
will be created by Spring in this case)
Once you change your service class, you can mock the objectMapper
as follows.
ObjectMapper mockObjectMapper = Mockito.mock(ObjectMapper.class);
Mockito.when(mockObjectMapper.readValue(anyString(), any(ConfigDetail.class)).thenReturn(configDetail);