我想存根一些代码,以便当一个参数与特定值匹配时,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