在同一个模拟上使用多个ArgumentMatchers

时间:2012-12-12 19:06:16

标签: java mockito

我试图在模拟中使用Mockito来做到这一点:
当使用argument1 - >调用Mock.someMethod(..)时返回结果1 当使用argument2调用Mock.someMethod(..)时 - >返回结果2 当使用argument3调用Mock.someMethod(..)时 - >返回result3

    when(mock.method(Matchers.argThat(new MyMatcher1() {

        @Override
        public boolean matches(Object arg0) {
                   // comparision logic
        }
    }))).thenReturn(result1);

    when(mock.method(Matchers.argThat(new MyMatcher2() {

        @Override
        public boolean matches(Object arg0) {
                   // comparision logic
        }
    }))).thenReturn(result2);

    when(mock.method(Matchers.argThat(new MyMatcher3() {

        @Override
        public boolean matches(Object arg0) {
                   // comparision logic
        }
    }))).thenReturn(result3);

但是Mockito正确地存储了第一个,但是在第二个上它会抛出NullPointer异常,因为它出于某种原因试图运行带有null agrument的Matcher。我不确定它是否得到支持。

如果这不是正确的方法,如何用Mockito实现这一目标?感谢。

3 个答案:

答案 0 :(得分:16)

而不是写

when(mock.method(Matchers.argThat(new MyMatcher1() {
    @Override
    public boolean matches(Object arg0) {
           // comparison logic
    }
}))).thenReturn(result1);

试试这个。

doReturn(result1).when(mock).method(Matchers.argThat(new MyMatcher1() {

    @Override
    public boolean matches(Object arg0) {
               // comparison logic
    }
}));

,同样适用于result2result3

这在http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#12描述,但在我看来,文档不清楚在这种情况下实际需要这种结构的事实。我将与Mockito团队的其他成员讨论如何改进文档。

祝你好运。

答案 1 :(得分:4)

根据经验,如果测试失败,您应该能够确定被测设备的错误。避免专门为一次测试编写自定义匹配器。 如果一个方法需要返回多个值,通常可以通过按测试预测的顺序返回值来简单地存根该方法。

e.g。

when(mock.method(any(Object.class))).thenReturn(result1, result2, result3);

这将在第一次调用时返回结果1,在第二次调用时返回result2,依此类推。

有很多情况下这是不够的,但通常情况下,更简单的测试是更好的。

答案 2 :(得分:1)

通过在自定义ArgumentMatcher中进行空检查,我现在能够解决问题。它起作用,因为NPE仅在启动时Mockito调用when()语句。它此时甚至不应该调用ArgumentMatcher.matches()!感觉就像Mockito中的一个错误。