使用powerMockito进行的JUnit测试为NPE提供了支持

时间:2018-06-23 19:34:32

标签: junit mockito powermockito

我有一个要为其编写Junit单元测试用例的类。

public class ComparatorUtil {

    public static Map<String, ValueDifference<Object>> compareJsonObject(Object srcObject, Object targetObject)
                throws JsonGenerationException, JsonMappingException, IOException {
        String initialJson = ConverterUtil.convertObjectToJson(srcObject);
        String updatedJson = ConverterUtil.convertObjectToJson(targetObject);
        Gson g = new Gson();
        Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
        Map<String, Object> firstMap = g.fromJson(initialJson, mapType);
        Map<String, Object> secondMap = g.fromJson(updatedJson, mapType);
        Map<String, MapDifference.ValueDifference<Object>> diffMap = Maps.difference(firstMap, secondMap).entriesDiffering();
        return diffMap;
    }
}


public class ConverterUtil {

    public static String convertObjectToJson(Object o)
            throws JsonGenerationException, JsonMappingException, IOException {
        ObjectMapper mapperObj = new ObjectMapper();
        return mapperObj.writeValueAsString(o);
    }
}

我写的Junit测试用例:-

@RunWith(PowerMockRunner.class)
@PrepareForTest(ConverterUtil.class)
public class ComparatorUtilTest {

    @Before
    public void setUp() {
        PowerMockito.mockStatic(ConverterUtil.class);
    }

    @Test
    public void testValueDiff() throws JsonGenerationException, JsonMappingException, IOException {
        TestObject srcObject = new TestObject();
        srcObject.setColor("white");
        srcObject.setId(1);
        TestObject targetObj = new TestObject();
        targetObj.setColor("white");
        targetObj.setId(1);
        targetObj.setSuffix("AA");
        ComparatorUtil.compareJsonObject(srcObject, targetObj);
        PowerMockito.verifyStatic(VerificationModeFactory.times(2));
        ConverterUtil.convertObjectToJson(srcObject);
        ConverterUtil.convertObjectToJson(targetObj);
    }
}

运行测试类时,我得到Null Pointer Exception,因为initialJsonupdatedJson将为空。谁能告诉我我在哪里做错了?

1 个答案:

答案 0 :(得分:1)

很多东西在这里错了。

  • 您似乎假设如何使用PowerMock。但是,您放在一起的东西根本就没有意义!例如,您需要使用'when()。thenReturn()'创建模拟规范
  • 含义:仅指示PowerMock某个类将被模拟是不够的。您必须告诉PowerMock有关调用这些静态方法时要返回的实际值的信息。
  • 因此,请从头至尾阅读一个不错的教程。不要将PowerMock用于自己的代码,而要看教程如何解决一个简单的问题。

然后:PowerMock需要一定的费用。因此,您避免使用它。您应该退后一步,研究重新编写代码,以便无需模拟静态方法即可对其进行测试。您看,我们正在谈论将一些输入转换成一些输出的代码。对于这种情况,您应该能够编写完全不需要模拟的生产和测试代码。如果有的话,您应该使用Mockito之类的框架-无需PowerMock即可测试良好的生产代码。

更具体地说:为什么需要模拟静态方法?这似乎表明您的ObjectMapper在单元测试设置中不起作用。它从这里开始!

您会看到,用于您的转换方法的单元测试应该看起来像这样:

assertThat(someConverterUnderTest.convert(fineTunedInput), is(expectedOutput));

就是这样!您应该设计转换器以在单元测试环境中完全工作。然后,模仿的所有需求就消失了。换句话说:您目前正在测试实施细节。相反,您应该始终尝试测试方法的公共合同。测试实现细节有时是不可避免的,但是如前所述:您在此处显示的代码实际上应该在没有模拟的情况下进行真正的测试。

然后:即使您需要模拟: static 方法也很麻烦。这明确表明您不应在此处使用 static !相反,您将那些可能需要模拟的元素转换为参数或被测类的字段。因为这样您就可以注入模拟对象。这意味着您不再需要PowerMock(ito)工具。