65

テスト中に特定のモックとの相互作用がなかったことを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
}

APrintStreamにはたくさんのメソッドがあり、個別の検証ですべてを検証したくありませんSystem.err

したがって、簡単な解決策があれば、テストカバレッジが良好であれば、ソフトウェアエンジニア(および私自身)に、変更をコミットする前に、System.out.println("Breakpoint#1");またはその前に、(私の)デバッグコードを削除するように強制できることを願っています。e.printStacktrace();

4

5 に答える 5

82

これを使って :

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);
}
于 2012-08-13T15:10:53.623 に答える
13
verifyZeroInteractions(systemOut);

コメントに記載されているように、これはスパイでは機能しません。

ほぼ同等ですが、より完全な回答については、この質問に対するゴンタードの回答を参照してください。

于 2012-08-13T14:28:08.637 に答える
5

少し異なるタックを試すことができます:

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 が示唆するように、匿名型をモックに切り替えて検証することもできます。

于 2012-08-13T14:52:00.807 に答える
2

この問題を解決する 1 つの方法は、テストしているクラスをリファクタリングして、出力に使用できる 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
    }
}

クラス自体内では、System.out を呼び出す場合は常に System.out の代わりに systemOut 変数を使用します。

次に、テスト クラス内で mock を作成し、PrintStreamそれを package-private コンストラクターに渡して、テストするオブジェクトを取得します。これで、テストから好きなアクションを実行verifyし、モックへの影響を確認するために使用できますPrintStream

于 2012-08-14T11:05:18.617 に答える