Java Mockito-如何验证从未调用过mock
我正在寻找一种方法来验证Mockito,在测试期间没有与给定的mock进行任何交互。对于具有验证模式Java Mockito-如何验证从未调用过mock,java,junit,mockito,Java,Junit,Mockito,我正在寻找一种方法来验证Mockito,在测试期间没有与给定的mock进行任何交互。对于具有验证模式never()的给定方法,很容易实现这一点,但我还没有找到完整模拟的解决方案 我真正想要实现的是:在测试中验证没有任何get打印到控制台。jUnit的总体思路如下: private PrintStream systemOut; @Before public void setUp() { // spy on System.out systemOut = spy(System.out
never()
的给定方法,很容易实现这一点,但我还没有找到完整模拟的解决方案
我真正想要实现的是:在测试中验证没有任何get打印到控制台。jUnit的总体思路如下:
private PrintStream systemOut;
@Before
public void setUp() {
// spy on System.out
systemOut = spy(System.out);
}
@After
public void tearDown() {
verify(systemOut, never()); // <-- that doesn't work, just shows the intention
}
私有打印流系统输出;
@以前
公共作废设置(){
//监视系统
systemOut=spy(System.out);
}
@之后
公共无效拆卸(){
验证(systemOut,never());//
正如评论中提到的,这对间谍不起作用
有关大致相同但更完整的答案,请参见gontard对此问题的回答。您可以尝试稍微不同的方法:
private PrintStream stdout;
@Before public void before() {
stdout = System.out;
OutputStream out = new OutputStream() {
@Override public void write(int arg0) throws IOException {
throw new RuntimeException("Not allowed");
}
};
System.setOut(new PrintStream(out));
}
@After public void after() {
System.setOut(stdout);
}
如果愿意,可以将匿名类型切换为模拟和验证。使用以下方法:
import static org.mockito.Mockito.verifyZeroInteractions;
// ...
private PrintStream backup = System.out;
@Before
public void setUp() {
System.setOut(mock(PrintStream.class));
}
@After
public void tearDown() {
verifyZeroInteractions(System.out);
System.setOut(backup);
}
解决此问题的一种方法是重构您正在测试的类,以允许注入可用于输出的PrintStream。这将允许您对其进行单元测试,而无需依赖系统
类的行为。您可以使用包私有构造函数进行此注入,因为您只会使用它来自相应的测试类。所以它可能看起来像这样
public class MyClass{
private PrintWriter systemOut;
public MyClass(){
this(System.out);
}
MyClass(PrintWriter systemOut){
this.systemOut = systemOut;
// ...any other initialisation processing that you need to do
}
}
在类本身中,使用systemOut变量而不是System.out,只要调用后者
现在,在test类中,制作一个mockPrintStream
,并将其传递给包私有构造函数,以获取要测试的对象。现在,您可以从测试中运行您喜欢的任何操作,并使用verify
检查它们对mockPrintStream
的影响,因为原始答案是正确的verifyZeroInteractions
已被弃用,请改用verifyNoInteractions
:
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
public class SOExample {
@Test
public void test() {
Object mock = mock(Object.class);
verifyNoInteractions(mock);
}
}
(facepalm)-但它似乎不适用于间谍活动,我必须模拟PrintStream,然后将其设置到系统上…在没有看到您的代码的情况下,我猜这对间谍失败的原因是,当您对间谍进行存根时,存根中的方法调用实际上算作一个待验证的方法。三条建议。(1)verifyNoMoreInvocations(Ignorsubs(mockOne,mockTwo));
-这将类似于verifyZeroInteractions
,但忽略您已经存根的内容。(2)您是否使用doReturn/doThrow/doAnswer
方法设置存根?在处理间谍问题时,这些方法通常比的
方法更有效。然后返回/然后抛出/然后
…继续建议(3)就是发布更多的代码,这样这里的人可以更好地帮助你。@David,我的代码示例已经完成。没有更多相关的行了。但是我期待着与mockito spies一起找到一个有效的解决方案。如果我可以只spySystem.out
而不是临时用mock替换流,那将更加优雅。好的,比ks,我现在更了解你的要求。我确实有一个不同于gontard和McDowell的解决方案-我现在没有时间发布,但我会在几个小时内发布。肯定是a+1。不幸的是,我这次对Mockito的解决方案感兴趣,因此我会接受另一个答案。希望你不介意:)看起来是我能得到的最好答案o感谢这种方法。谢谢!(实际上,我已经将大部分逻辑隐藏在一个helper类中,并且还必须使记录器静音;))verifyZeroInteractions现在已经被弃用,取而代之的是org.mockito.mockito#verifyNoInteractions
啊,好吧,但这并不完全是我想要做的:我试图找到一种方法来测试一个类而不去碰它,特别是不添加只用于测试的代码nder测试,那么这真是一个很好的方法!
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
public class SOExample {
@Test
public void test() {
Object mock = mock(Object.class);
verifyNoInteractions(mock);
}
}