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

vmjh9lq9  于 2023-10-18  发布在  其他
关注(0)|答案(4)|浏览(138)

我正在测试一个服务层,不知道如何在该类中模拟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"));
    }
}
daolsyd0

daolsyd01#

问题在于这一行,你在这里模拟了对objectmapper的调用。

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

正确语法为

Mockito.when(objMapper.readValue(“”,ConfigDetail.class)).thenReturn(configDetail);
注意括号的位置。使用Spy或Verify时,括号位置不同。当使用when-then语法时,

k97glaaz

k97glaaz2#

使用您当前的Service类很难模拟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,而是从外部注入(在这种情况下,objectMapper将由Spring创建)
一旦更改了服务类,就可以模拟objectMapper,如下所示。

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

tzdcorbm3#

在SUT中创建的Mocking对象是Mockito的最大限制。使用jmockit或powerMock或checkout官方的mockito方法来处理这个问题。https://github.com/mockito/mockito/wiki/Mocking-Object-Creation

gv8xihay

gv8xihay4#

如果你使用的是junit 5,下面一行模拟Objectmapper readvalue(String,Class)方法。为了避免readValue方法中的歧义,我们使用了类型转换。

@Mock
ObjectMapper objMapper;
Mockito.when(objMapper.readValue((String)Mockito.any(),Mockito.any(Class.class))).thenReturn(configDetail);

相关问题