如何在Mockito中固执以匹配一个参数



我想存根一些代码,以便当一个参数与特定值匹配时,vararg方法返回true。例如,给定我无法更改的现有代码:

(在这里使用Kotlin,但我认为这适用于任何Java情况。)

class Foo {
    fun bar(vararg strings : String) : Boolean {
        // Iterates `strings` and returns true when one satisfies some criteria
    }
}

...我想编写与此类似的存根代码:

val foo = Foo()
whenever(foo.bar(eq("AAA"))).thenReturn(true)

当调用为恰好 foo.bar("AAA")

时,此功能正常

但是,有时候测试的代码会导致调用foo.bar("AAA", "BBB"),在这种情况下,它失败了。

如何修改存根代码,以便在调用中传递任何数量的vararg时起作用?

编辑标记为可能的重复;在这种情况下,该方案考虑了呼叫中的varargs的完全遗漏。在这里,我正在尝试匹配varargs数组的一个特定元素。

您必须将方法固执2次。首先是最不具体的存根:

val foo = Foo()
whenever(foo.bar(any())).thenReturn(false) // or whatever you want to return/throw here

,然后是更具体的单个参数方法:

whenever(foo.bar(eq("AAA"))).thenReturn(true)

在您的评论后,您可以使用类似的东西(这次使用Java):

when(foo.bar(any())).thenAnswer(invocation -> {
    for (Object argument : invocation.getArguments()) {
        if ("AAA".equals(argument)) return true;
    }
    return false;
});

在kotlin中相同

whenever(foo.bar(any()).thenAnswer {
    it.arguments.contains("AAA")
}

您可以创建自己的matcher

public class MyVarargMatcher extends ArgumentMatcher<String[]> implements VarargMatcher
{
    private String expectedFirstValue;
    public MyVarargMatcher(String expectedFirstValue)
    {
        this.expectedFirstValue = expectedFirstValue;
    }
    @Override
    public boolean matches(Object varargArgument) {
        if (varargArgument instanceof String[])
        {
            String[] args = (String[]) varargArgument;
            return Stream.of(args).anyMatch(expectedFirstValue::equals);
        }
        return false;
    }
}

然后使用它(Java代码):

Foo foo = Mockito.mock(Foo.class);
Mockito.doReturn(true).when(foo).bar(Mockito.argThat(new MyVarargMatcher("AAA")));

用OP的评论进行了编辑:只要" AAA"是Args之一,它应该返回true

相关内容

  • 没有找到相关文章

最新更新