使用ArgumentMatcher时发生NullPointerException

1 java junit mocking matcher mockito

我编写了以下使用的JUnit测试ArgumentMatchers

    MyClass classUnderTest = new MyClass();

    class AnyBooleanMatcher extends ArgumentMatcher<Boolean> {
        public boolean matches(Object argument) {
            return ((Boolean) argument).equals(Boolean.TRUE);
        }
    }

    class MyObjectMatcher extends ArgumentMatcher<MyObject> {
        public boolean matches(Object argument) {
            return ((MyObject) argument).getValue().equals("123");
        }
    }

    final Service mockService = mock(Service.class);

    when(mockService.search(Matchers.argThat(new MyObjectMatcher()),
            Matchers.argThat(new AnyBooleanMatcher())));

    classUnderTest.callMethod(mock(ActionEvent.class));

    verify(mockService).search(Matchers.argThat(new MyObjectMatcher()),
            Matchers.argThat(new AnyBooleanMatcher()));
Run Code Online (Sandbox Code Playgroud)

不幸的是,我NullPointerExceptionwhen声明中总是收到。

我什至知道为什么:argThat返回nullJavaDoc中指定的。但是,我不知道为什么示例中的建模方式完全相同时,我的测试为什么不起作用。

Bri*_*ice 5

您有一个NullPointerException原因,因为方法签名使用的是本机类型,而您使用的是Matchers.argThat,它返回一个对象。

编译后,Javac将在周围添加自动拆箱代码Matchers.argThat(new AnyBooleanMatcher()),正如您所说的,它null会导致NPE。

我敢肯定intThatbooleanThat在处理本机类型时,mockito的Javadoc也说要使用style方法。使用这些将防止编译器引入自动拆箱代码。

在另一个主题上,我建议您编写这样的代码,以使其更具可读性。

when(mockService.search(argThat(hasValue("123")), booleanThat(isTrue()))).thenReturn("something");

// ...

private AnyBooleanMatcher isTrue() {
    return new AnyBooleanMatcher();
}

private MyObjectMatcher hasValue(String value) {
    return new MyObjectMatcher(value);
}
Run Code Online (Sandbox Code Playgroud)