java - Mockito NullPointerException 在 InvocableMatcher 上调用 equals

标签 java junit mockito

我是 Mockito 新手,在尝试模拟第三方类时遇到错误。

堆栈跟踪:

java.lang.NullPointerException
at MockitoTest.equals(MockitoTest.java:34)
at org.mockito.internal.invocation.InvocationMatcher.matches(InvocationMatcher.java:58)
at org.mockito.internal.stubbing.InvocationContainerImpl.findAnswerFor(InvocationContainerImpl.java:75)
at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:87)
at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29)
at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:38)
at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:51)
at MockitoTest$$EnhancerByMockitoWithCGLIB$$cde393a2.getSomethingElse(<generated>)
at MockitoTestTest.test(MockitoTestTest.java:19)

Mockito 正在此模拟上调用 equals 方法,该模拟没有设置一些私有(private)成员。代码:

public void test() {
    final String something = "something";
    final String somethingElse = "somethingElse";

    MockitoTest mt = Mockito.mock(MockitoTest.class);
    when(mt.getSomething()).thenReturn(something);
    when(mt.getSomethingElse()).thenReturn(somethingElse);

被模拟的类定义如下:

public class MockitoTest {

private final String something;
private volatile String somethingElse;

public MockitoTest(String theThing){
    something = theThing;
}

public String getSomething(){
    return something;
}

public String getSomethingElse(){
    return somethingElse;
}

@Override
public final int hashCode() {
    return something.hashCode();
}

@Override
public final boolean equals(Object o) {
    if(!(o instanceof MockitoTest))
        return false;
    return something.equals(((MockitoTest)o).something);
}

}

很明显,来自 equals() 的 NPE 正在发生,因为构造函数未运行且“某些内容”未设置。

我的问题:为什么在第二次调用 when() 时会发生这种情况?有没有办法阻止 equals 方法被调用?我做错了什么吗?

注意:上面的示例是为了显示错误的发生而设计的。我试图模拟的真正类位于第三方库中,无法轻易更改。它的构造并不简单,并且需要一个在第三方包之外不可见的类型。除了在他们的包中编写我的测试之外,我还能做些什么来模拟它,正如上面尝试的那样?

最佳答案

我相当确定您的问题是您尝试模拟的类中的 equalshashCodefinal 。 Mockito 需要重写这些方法;所以这个类可能是不可模拟的。

无论如何, mock 第三方类通常是一件坏事。您是否可以重构您的应用程序以便包装第三方类?您的包装器应该仅公开您需要使用的方法。当您编写单元测试时,您可以只模拟包装器。

关于java - Mockito NullPointerException 在 InvocableMatcher 上调用 equals,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21391189/

相关文章:

java - 如何在 Java 中将 "null"值分配给 int[] 数组中的单个元素

java - 与另一个一起启动一个主类

java - org.junit 包不存在

java - 任何模拟 Files.write(...) 方法的方法?

java - 使用 Oracle SQL 结果集填充 Java swing JComboBox

java - 我们可以在 AES 或 DES 中使用相同的 key 吗

java - 找不到合适的驱动程序的原因

java - JUnit 测试 - 我可以设置我的数据库连接以避免测试由于达到最大数据库连接而失败

unit-testing - java.lang.NoClassDefFoundError : org/objenesis/ObjenesisStd with Mockito 错误

java - 使用 mockito 模拟父类(super class)方法调用不起作用