使用ArgumentMatcher时出现NullPointerException

时间:2011-11-09 07:32:22

标签: java junit mocking mockito matcher

我编写了以下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()));

不幸的是,我总是在NullPointerException语句中获得when

我甚至知道原因:argThat返回null,如JavaDoc中所指定的那样。但我不知道为什么我的测试不起作用,example中的那些 - 以完全相同的方式建模 - 确实有效。

2 个答案:

答案 0 :(得分:4)

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

编译时,Javac会在Matchers.argThat(new AnyBooleanMatcher())周围添加自动取消装箱代码,正如您所说,它会返回null,因此您可以了解NPE的原因。

我很确定mockito的Javadoc也会说在处理本机类型时使用intThatbooleanThat样式方法。使用这些将阻止编译器引入的自动拆箱代码。

关于另一个话题,我建议你编写这样的代码,以使其更具可读性。

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);
}

答案 1 :(得分:0)

如果您正在寻找when.. thenReturn..语法:

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