我正在为FizzConfigurator
类编写单元测试,如下所示:
public class FizzConfigurator {
public void doFoo(String msg) {
doWidget(msg, Config.ALWAYS);
}
public void doBar(String msg) {
doWidget(msg, Config.NEVER);
}
public void doBuzz(String msg) {
doWidget(msg, Config.SOMETIMES);
}
public void doWidget(String msg, Config cfg) {
// Does a bunch of stuff and hits a database.
}
}
我想编写一个简单的单元测试来存根doWidget(String,Config)
方法(这样它实际上不会触发并命中数据库),但这样我就可以验证调用doBuzz(String)
最终会执行doWidget
。 Mockito似乎是这里工作的合适工具。
public class FizzConfiguratorTest {
@Test
public void callingDoBuzzAlsoCallsDoWidget() {
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
Mockito.when(fixture.doWidget(Mockito.anyString(), Config.ALWAYS)).
thenThrow(new RuntimeException());
try {
fixture.doBuzz("This should throw.");
// We should never get here. Calling doBuzz should invoke our
// stubbed doWidget, which throws an exception.
Assert.fail();
} catch(RuntimeException rte) {
return; // Test passed.
}
}
}
这个似乎就像一个好的游戏计划(至少对我来说)。但是当我实际编写代码时,我在测试方法的第二行(Mockito.when(...)
行:
Mockito类型中的(T)方法不适用于参数(void)
我看到Mockito无法模拟返回void
的方法。所以我问:
doBuzz
调用doWidget
?和doWidget
,因为它是我整个FizzConfigurator
课程中最关键的方法?答案 0 :(得分:24)
我不会使用例外来测试,而是验证。另一个问题是,您不能将when()
与返回void的方法一起使用。
我将如何做到这一点:
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
doNothing().when(fixture).doWidget(Mockito.anyString(), Mockito.<Config>any()));
fixture.doBuzz("some string");
Mockito.verify(fixture).doWidget("some string", Config.SOMETIMES);
答案 1 :(得分:0)
这清楚地表明doWidget
方法应属于FizzConfigurator
依赖的另一个类。
在您的测试中,这个新的依赖项将是一个模拟,您可以轻松验证是否使用verify
调用了它的方法。
答案 2 :(得分:0)
对于我来说,对于我想存根的方法,我传入了不正确的匹配器。
我的方法签名(对于我试图存根的超类方法):字符串,对象。
我正在传递:
myMethod("string", Mockito.nullable(ClassType.class))
并获得:
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
在另一个参数中使用匹配器时,我们还需要在字符串中使用一个:
myMethod(eq("string"), Mockito.nullable(ClassType.class))
希望这会有所帮助!
答案 3 :(得分:0)
这不是问题的直接答案,但我在尝试解决我的问题时遇到了它,此后一直没有找到更相关的问题。
如果您尝试存根/模拟标记为 Spy 的对象,则 Mockito 仅选取使用 JB Nizet 暗示的 do...when
约定创建的存根:
doReturn(Set.of(...)).when(mySpy).getSomething(...);
它没有被接收:
when(mySpy.getSomething(...)).thenReturn(Set.of(...));
与 MockHandlerImpl::handle
中的评论匹配:
// stubbing voids with doThrow() or doAnswer() style