如何使用mockito模拟ObjectMapper.readValue()

时间:2018-02-02 03:38:33

标签: junit mockito

我正在测试服务层,但不确定如何在该类中模拟ObjectMapper().readValue。我对mockito相当新,并且可以弄清楚如何做到这一点。

以下是我的代码,

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

运行此测试时,我得到以下结果,

com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input
 at [Source: (String)""; line: 1, column: 0]

在这里发布ServiceTest.Java

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

3 个答案:

答案 0 :(得分:2)

使用您当前的服务类,很难模拟ObjectMapperObjectMapperfetchConfigDetail方法紧密相关。

您必须按照以下方式更改服务类以模拟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);
    }
}

我在这里所做的不是在我从外部注入的方法中创建objectMapper(在这种情况下,Spring将创建objectMapper

更改服务类后,您可以按如下方式模拟objectMapper

ObjectMapper mockObjectMapper = Mockito.mock(ObjectMapper.class);
Mockito.when(mockObjectMapper.readValue(anyString(), any(ConfigDetail.class)).thenReturn(configDetail);

答案 1 :(得分:2)

问题在于您正在模拟对objectmapper的调用。

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

语法正确

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

注意支架位置。使用Spy或Verify时,支架位置为diff。然后当使用when-then语法时。

答案 2 :(得分:1)

模拟在SUT中创建的对象是IMO模拟的最大限制。使用jmockit或powerMock或检查处理此问题的官方mockito方式。 https://github.com/mockito/mockito/wiki/Mocking-Object-Creation