【问题标题】:How to pass null string to a private method using jmockit while unit testing it?如何在单元测试时使用 jmockit 将空字符串传递给私有方法?
【发布时间】:2025-12-05 22:20:03
【问题描述】:

下面是我在DataTap 类中的私有方法,我正在尝试使用 jmockit 对这个私有方法进行 junit 测试 -

private void parseResponse(String response) throws Exception {
    if (response != null) {
        // some code
    }
}

所以下面是我写的 junit 测试,但对于 null 情况,它以某种方式在 junit 测试本身上抛出 NPE。

DataTap tap = new DataTap();
Deencapsulation.invoke(tap, "parseResponse", "hello");

// this line throws NPE
Deencapsulation.invoke(tap, "parseResponse", null);

所以我的问题是 - 有什么方法可以使用 JMOCKIT 作为 junit 测试的一部分将 null string 传递给 parseResponse 方法吗?

这就是我在那条线上看到的 -

null 类型的参数应该显式转换为 Object[] 可变参数方法的调用 invoke(Object, String, Object...) 从类型解封装。它也可以转换为 Object 对于可变参数调用

【问题讨论】:

  • 该代码应该可以工作。我认为问题出在其他地方。
  • 这是我在The argument of type null should explicitly be cast to Object[] for the invocation of the varargs method invoke(Object, String, Object...) from type Deencapsulation. It could alternatively be cast to Object for a varargs invocation 那行看到的,它确实失败了。

标签: java junit jmockit


【解决方案1】:

快速浏览at the documentation 表明您尝试使用该签名执行的操作是不可能的:

...如果需要传递空值,则必须传递参数类型的Class对象

如果是这种情况,则传入 Class 对象以及实例。

Deencapsulation.invoke(tap, "parseResponse", String.class);

【讨论】:

  • 谢谢诚。我试过了,我得到了Invalid null value passed as an Argument 1。有什么建议吗?
  • 传递null 的Class 对象而不是,而不是添加它:Deencapsulation.invoke(tap, "parseResponse", String.class)。因为方法重载,JMockit需要知道每个参数的类型,这样才能通过Reflection找到想要的方法;这种类型只能通过非空参数通过在对invoke(...)的调用中显式传递来确定。
  • 文档现在位于:jmockit.org/tutorial/…
  • @jordanpg:鼓励使用新文档编辑答案。
  • 答案似乎含糊不清。我不得不使用空列表 arg 调用方法。这有效: Deencapsulation.invoke(theObject, "methodName", List.class);
【解决方案2】:

按照错误所说的去做。也就是把这一行改成这样:

Deencapsulation.invoke(tap, "parseResponse", (Object) null);

【讨论】:

  • 谢谢tbodt。我试过这个,我得到了Invalid null value passed as an Argument 0。有什么建议吗?
【解决方案3】:

当我需要在 toString 方法中传递空字符串时,我确实喜欢这样做,即通过将 null 转换为所需的类型

mockedObject.toString((String) null)

【讨论】:

    【解决方案4】:

    您正在使用便捷方法,您需要使用完整方法。有两种方法可以调用对象实例上的方法。第一种方法是从 nonNullArgs 中获取 parameterTypes。

    Deencapsulation.invoke(instance, methodName, nonNullArgs);
    Deencapsulation.invoke(instance, methodName, parameterTypes, methodArgs);
    

    如果其中一个 args 为 null,则需要传入 parameterTypes,如下所示:

    DataTap tap = new DataTap();
    String response = null;
    Class[] parameterTypes = { String.class };
    Deencapsulation.invoke(tap, "parseResponse", parameterTypes, response);
    

    【讨论】: