How to mock ObjectMapper.readValue() using mockito

非 Y 不嫁゛ 提交于 2020-06-24 22:48:37

问题


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,

service.java

private configDetail fetchConfigDetail(String configId) throws IOException {
    final String response = restTemplate.getForObject(config.getUrl(), String.class);
    return new ObjectMapper().readValue(response, ConfigDetail.class);
}

ServiceTest.java

@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"));
    }
}

回答1:


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);



回答2:


Problem is with the this line where you are mocking the call to objectmapper.

Mockito.when((objMapper).readValue(“”,ConfigDetail.class)).thenReturn(configDetail);

Correct syntax is

Mockito.when(objMapper.readValue(“”,ConfigDetail.class)).thenReturn(configDetail);

Notice the bracket position. When using Spy or Verify, the bracket position is diff. then when using when-then syntax.




回答3:


Mocking objects created in a SUT is IMO the single biggest limitation of mockito. Use jmockit or powerMock or checkout the offical mockito way of handling this. https://github.com/mockito/mockito/wiki/Mocking-Object-Creation



来源:https://stackoverflow.com/questions/48575356/how-to-mock-objectmapper-readvalue-using-mockito

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!