【问题标题】:PowerMock whenNew Not Returning Mocked InstancePowerMock whenNew 不返回模拟实例
【发布时间】:2018-05-25 14:05:21
【问题描述】:

我正在尝试使用 PowerMock 来拒绝对 Jackson ObjectMapper 的调用,但由于某种原因它无法正常工作,我怀疑它与 whenNew 在被测试的方法中实例化它时实际上没有提供模拟实例有关.

这是一个我们无法真正更改的遗留代码库,因此我们只能使用 PowerMock 来满足测试覆盖率要求...

我有一个类似以下的方法:

private void intakeDataFromUrl(URL url) {
    ObjectMapper mapper = new ObjectMapper();
    DataDTO[] dataDtos = mapper.readValue(url, DataDTO[].class)

    // other code
}

在单元测试中,我尝试执行以下操作:

@Test
public void test_intakeDataFromUrl() {

    DataDTO[] data = this.createMockData();

    ObjectMapper mapper = mock(ObjectMapper.clas);

    whenNew(ObjectMapper.clas)
        .withNoArguments()
        .thenReturn(mapper);

    // mock call to return mocked data
    doReturn(data)
        .when(mapper, "readValue", any(URL.class), any(DataDTO[].class))
}

但是在被测试的代码中,dataDtos 总是为空,然后下一段代码总是失败。

编辑:

看起来这条线可能是问题所在,尽管查看其他示例它应该可以工作。

// mock call to return mocked data
doReturn(data)
    .when(mapper, "readValue", any(URL.class), any(DataDTO[].class))

我还在最后一个参数上尝试了 isA 和 eq,但没有成功,仍然返回 null。

【问题讨论】:

  • 你能分享一下测试类的定义吗?是否用@PrepareForTest注解?
  • 我用真实代码做了一个例子,因为它不允许被共享,但是这个类是用@PrepareForTest注解的,它有 ObjectMapper.class 以及被测试的类
  • doReturn 调用的问题。应该是Mockito.when(mapper.readValue(..., ...)).thenReturn(...);。见this answer

标签: java unit-testing powermock


【解决方案1】:

whenNewObjectMapper 的以下使用成功:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ObjectMapper.class})
public class WtfTest {

    @Test
    public void test_intakeDataFromUrl() throws Exception {
        String in = "in";
        String out = "out";

        ObjectMapper mapper = mock(ObjectMapper.class);

        PowerMockito.whenNew(ObjectMapper.class)
                .withNoArguments()
                .thenReturn(mapper);

        Mockito.when(mapper.readValue(in, String.class)).thenReturn(out);

        assertEquals(out, intakeDataFromUrl(in));
    }

    private String intakeDataFromUrl(String url) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(url, String.class);
    }
}

虽然这个例子没有使用DataDTO,但它与你的例子是一致的,并且是功能性的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多