以下代码:
ObjectMapper mapper = Mockito.mock(ObjectMapper.class);
Mockito.doThrow(new IOException()).when(mapper).writeValue((OutputStream) Matchers.anyObject(), Matchers.anyObject());
Mockito.doNothing().when(mapper).writeValue((OutputStream) Matchers.anyObject(), Matchers.anyObject());
try {
mapper.writeValue(new ByteArrayOutputStream(), new Object());
} catch (Exception e) {
System.out.println("EXCEPTION");
}
try {
mapper.writeValue(new ByteArrayOutputStream(), new Object());
} catch (Exception e) {
System.out.println("EXCEPTION");
}
Run Code Online (Sandbox Code Playgroud)
预期的产出是
例外
对?
但我一无所获
如果我在doNothing之后做了doThrow我得到了
例外情况
除外
所以它看起来像是最后一个被嘲笑的模拟......我认为它会按照他们注册的顺序进行模拟吗?
我想制作一个模拟第一次抛出异常,第二次正常完成...
Jef*_*ica 16
Mockito可以使用相同的参数来连续行为 - 永远重复最终指令 - 但它们都必须属于同一个"链".否则Mockito会有效地认为你已经改变了主意并覆盖了之前被嘲弄的行为,如果你在一个setUp或多个@Before方法中建立了良好的默认值并希望在特定的测试用例中覆盖它们,这不是一个糟糕的特性.
一般规则"这行动的Mockito接下来会发生":在近期被定义的最链,所有的参数匹配将被选中.在链中,每个动作将发生一次(thenReturn如果给出的话,计算多个值thenReturn(1, 2, 3)),然后最后一个动作将永远重复.
// doVerb syntax, for void methods and some spies
Mockito.doThrow(new IOException())
.doNothing()
.when(mapper).writeValue(
(OutputStream) Matchers.anyObject(), Matchers.anyObject());
Run Code Online (Sandbox Code Playgroud)
这相当于thenVerb更常见when语法中的链式语句,您在此处正确避免使用该void方法:
// when/thenVerb syntax, to mock methods with return values
when(mapper.writeValue(
(OutputStream) Matchers.anyObject(), Matchers.anyObject())
.thenThrow(new IOException())
.thenReturn(someValue);
Run Code Online (Sandbox Code Playgroud)
请注意,您可以使用静态导入Mockito.doThrow和Matchers.*,并切换到any(OutputStream.class)而不是(OutputStream) anyObject(),并结束:
// doVerb syntax with static imports
doThrow(new IOException())
.doNothing()
.when(mapper).writeValue(any(OutputStream.class), anyObject());
Run Code Online (Sandbox Code Playgroud)
有关可以链接的完整命令列表,请参阅Mockito的Stubber文档.