【问题标题】:Whitebox invokeMethod with eq("string")带有 eq("string") 的白盒调用方法
【发布时间】:2026-02-27 07:20:10
【问题描述】:

我有考试

 Document document = spy(new Document());
    Whitebox.setInternalState(documentReceiverInteractor, "document", document);

    String text= "string";

    Whitebox.invokeMethod(documentReceiverInteractor, "saveFields", anyString(), eq(text), anyString(),
            anyString(), anyString(), anyString(), anyString());

    verify(document).setText(text);

启动后,我得到这个错误:

 Argument(s) are different! Wanted:
document.setText(
    <any string>
);
-> at ru.psbank.msb.dev.business.document.edit.receiver.DocumentReceiverInteractorTest.saveFields(DocumentReceiverInteractorTest.java:98)
Actual invocation has different arguments:
document.setText(
    null
);

eq 可以很好地处理原语并且没有对象。我该怎么办?

【问题讨论】:

  • 您是否尝试过调试测试调用? null 是否真的通过了?
  • 你为什么首先使用 Matchers 调用方法?你期望那里发生什么。 eq("text") 不是字符串“文本”。匹配器用于verifywhen 等,但不用于实际的方法调用。 anyString() 例如返回一个空字符串而不是任何字符串。 eq("text") 在直接调用中使用时可能会返回 null。您只是在错误的地方使用了 Matchers。从您的方法调用中删除匹配器,一切都会好起来的。

标签: android testing mockito powermock


【解决方案1】:
Whitebox.invokeMethod(documentReceiverInteractor, "saveFields",
    anyString(), eq(text), anyString(),
    anyString(), anyString(), anyString(), anyString());

这种说法没有意义。对anyString() 等的调用是对Mockito 的信号只有在对whenverify 的调用中才有意义。它们的返回值为null0""或其他虚拟值,以及their side effects are to modify Mockito's internal state;它们不是用于测试的随机或任意值,并且对于 Whitebox 没有任何特殊行为。

(在后台,您使用来自eq(text) 的返回值(即null)调用setText,并将其与您不小心添加到参数中的对anyString() 的调用之一进行匹配匹配器堆栈。)

相反,选择特定值:

Whitebox.invokeMethod(documentReceiverInteractor, "saveFields",
    "string 1",
    text,
    "string 2",
    "string 3",
    "string 4",
    "string 5",
    "string 6");

...而不是使用 Whitebox,它位于 Mockito 的 internalorg.mockito.internal.util.reflection 并且是 deleted in Mockito 2.2,您应该考虑使方法调用更加可见(如果您的测试在相同的包,如果没有,则公开)。毕竟,您的测试是您班级的消费者。如果您选择走这条路,请考虑添加@VisibleForTesting 或其他一些文档(如/** Visible for testing. */)。

【讨论】: