在同一模拟上使用多个参数匹配器

2022-09-02 12:23:51

我试图在 Mock 上使用 Mockito 执行此操作:
当 Mock.someMethod(..) 使用 argument1 调用时 -->返回 result1
当 Mock.someMethod(..) 使用 argument2 调用时 -->返回 result2
当 Mock.someMethod(..) 使用 argument3 调用时 -->返回 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实现这一目标?谢谢。


答案 1

而不是写作

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 团队的其他成员讨论如何改进此处的文档。

祝你好运。


答案 2

根据经验,如果测试失败,您应该能够查明所测试单元的问题所在。避免专门为一个测试编写自定义匹配器。如果一个方法需要返回多个值,通常只需按测试预测的顺序返回值来存根该方法就足够了。

例如:

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

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

显然,在某些情况下,这是不够的,但通常情况下,更简单的测试是更好的测试。


推荐