Mockito - 如何验证模拟从未被调用过

时间:2012-08-13 14:23:39

标签: java junit mockito

我正在寻找一种方法来验证Mockito,在测试期间没有与给定模拟器的任何交互。对于使用验证模式never()的给定方法,很容易实现,但我还没有找到完整模拟的解决方案。

我实际想要实现的目标:在测试中验证,没有任何内容打印到控制台。 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
}

PrintStream有很多方法,我真的不想用单独的验证验证每一个方法 - System.err也是如此......

所以我希望,如果有一个简单的解决方案,我可以,鉴于我有一个很好的测试覆盖率,强迫软件工程师(和我自己)删除他们的(我的)调试代码,如System.out.println("Breakpoint#1");或{在提交更改之前{1}}。

5 个答案:

答案 0 :(得分:59)

使用此:

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);
}

答案 1 :(得分:11)

verifyZeroInteractions(systemOut);

如评论中所述,这不适用于间谍。

对于大致相当但更完整的答案,请参阅gontard对此问题的回答。

答案 2 :(得分:4)

您可以尝试稍微不同的方法:

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);
}

如果您愿意,可以为模拟切换匿名类型并验证as Don Roby suggests

答案 3 :(得分:2)

解决此问题的一种方法是重构您正在测试的类,以允许注入可用于输出的PrintStream。这将允许您对其进行单元测试,而不依赖于System类的行为。您可以使用package-private构造函数进行此注入,因为您只能从相应的测试类中使用它。所以它可能看起来像这样。

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,只要你调用后者。

现在,在测试类中,创建一个模拟PrintStream,并将其传递给package-private构造函数,以获取您要测试的对象。现在,您可以在测试中运行您喜欢的任何操作,并使用verify检查它们对模拟PrintStream的影响。

答案 4 :(得分:2)

由于最初的正确答案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);
    }
}