簡體   English   中英

Mockito - 如何驗證從未調用過模擬

[英]Mockito - how to verify that a mock was never invoked

我正在尋找一種方法來驗證 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"); e.printStacktrace(); 在提交更改之前。

用這個 :

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);
}
verifyZeroInteractions(systemOut);

如評論中所述,這不適用於間諜。

有關大致等效但更完整的答案,請參閱 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);
}

如果您願意,您可以切換模擬的匿名類型並按照 Don Roby 的建議進行驗證。

由於原始正確答案, 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);
    }
}

解決此問題的一種方法是重構您正在測試的類,以允許注入可用於輸出的 PrintStream。 這將讓您對其進行單元測試,而無需依賴System類的行為。 您可以為此注入使用包私有構造函數,因為您只會從相應的測試類中使用它。 所以它可能看起來像這樣。

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 ,並將其傳遞給包私有構造函數,以獲取您要測試的對象。 現在,您可以從測試中運行您喜歡的任何操作,並使用verify檢查它們對您的模擬PrintStream

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM