以下代码:
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");
}
预期输出
异常
正确?
但我什么都没得到
如果我在doNothing之后再做了doThrow
异常
例外
所以它看起来像是最后一个被嘲笑的模拟......我认为它会按照他们注册的顺序进行模拟吗?
我正在制作一个模拟第一次抛出异常并且第二次正常完成......
答案 0 :(得分:15)
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());
这相当于更常见的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);
请注意,您可以对Mockito.doThrow
和Matchers.*
使用静态导入,并切换到any(OutputStream.class)
而不是(OutputStream) anyObject()
,最后结束:
// doVerb syntax with static imports
doThrow(new IOException())
.doNothing()
.when(mapper).writeValue(any(OutputStream.class), anyObject());
有关可以链接的完整命令列表,请参阅Mockito's documentation for Stubber。