每当使用非预定义参数调用模拟时,是否可以抛出异常?有Answers.RETURNS_SMART_NULLS
,但这不是我真正需要的,因为如果null
是合法的返回值,它不起作用,这不会导致NullPointerException
,而是以后的错误。
编辑:一些背景。因此,在 Mockito 中定义模拟时,您可以为每个调用指定返回值,如下所示:
when(myMock.someMethod(arg1, arg2)).thenReturn(returnValue);
当使用参数调用myMock.someMethod
时,我没有在测试中给出返回值,它只是返回null
.我想将其配置为立即崩溃,并告诉我我忘记为某些参数组合定义返回值。
编辑 2:有人建议提供一个自定义defaultAnswer
,该在调用时会引发异常。不幸的是,这不起作用。即使存在模拟,也会调用默认答案的answer()
方法。下面是一个示例:
public class Test {
public static class Adder {
public int add(int a, int b) {
return a + b;
}
}
public static final Answer<Object> THROW_ON_UNDEFINED_ARGS = new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
throw new IllegalArgumentException(
String.format("Calling a mock with undefined arguments: %s %s",
invocation.getMethod(),
Arrays.toString(invocation.getArguments())));
}
};
public static void main(String[] args) {
Adder adderMock = mock(Adder.class, THROW_ON_UNDEFINED_ARGS);
when(adderMock.add(2, 3)).thenReturn(5);
System.out.println(adderMock.add(2, 3));
}
}
即使定义了adderMock.add(2, 3)
也会引发异常。
您可以在模拟的构造中提供一个默认Answer
,该总是抛出异常。然后,每个存根的呼叫都将像往常一样运行。这些路径之外的所有内容都将引发异常。像这样:
final String arg = "some arg";
Collection<Object> object = mock(Collection.class, new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
throw new IllegalArgumentException("You cannot invoke " + invocation.getMethod() +
" with " + Arrays.toString(invocation.getArguments()));
}
});
doReturn(true).when(object).add(arg);
object.add(arg); // Goes ok
object.add("azertyuiop"); // Throws the exception
只需指出另一种方法,您可以使用thenAnswer
:
when(myMock.someMethod(anyString(), anyString())).
thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String arg1 = (String) args[0];
String arg2 = (String) args[1];
if ("arg1".equals(arg1) && "arg2".equals(arg2)) return "someValue";
throw new Exception();
}
});
myMock.someMethod("arg1", "arg2"); // Returns "someValue"
myMock.someMethod("xxx", "yyy"); // Throws Exception
希望对您有所帮助。
首先,有点"好的工程"喃喃自语 - 你为什么要这样做?Mockito试图"提升"BDD风格 - 你设置(模拟(你的调用,你执行代码并验证交互是否完全符合你的预期,而不是"它没有调用任何其他东西" - 你是否尝试做一些在查找不相关的调用中描述的事情?一般来说,如果我想模拟所有情况,但有一个 - 这让我问自己我的测试是否真的可以。
无论如何,对于主题:)
在 Mockito 中,您可以使用不同的值定义多个when
,例如
class Foo {
public String bar(int a) {
return "bar = " + a;
}
}
Mockito.when(task.bar(Matchers.anyInt())).thenReturn("L")
Mockito.when(task.bar(3)).thenThrow(new IllegalAccessError())
task.bar(4); // returns "L"
task.bar(3); //throws IllegalAccessError
请注意,when
的顺序确实很重要。规则以相反的顺序处理(或者更确切地说,覆盖实际的匹配器(。在我的代码中,我们首先模拟 anyInt,然后模拟 3 - 这有效。如果反转它 - 对bar()
的两个调用都将返回"L"。