Mockitoを使用して特定のメソッドが呼び出されなかったことを確認するにはどうすればよいですか?


625

オブジェクトの依存関係でメソッドが呼び出されていないことを確認するにはどうすればよいですか?

例えば:

public interface Dependency {
    void someMethod();
}

public class Foo {
    public bar(final Dependency d) {
        ...
    }
}

Fooテストでは:

public class FooTest {
    @Test
    public void dependencyIsNotCalled() {
        final Foo foo = new Foo(...);
        final Dependency dependency = mock(Dependency.class);
        foo.bar(dependency);
        **// verify here that someMethod was not called??**
    }
}

回答:


1087

さらに意味のある:

import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

// ...

verify(dependency, never()).someMethod();

この機能のドキュメントには、§4「呼び出しの正確な数の検証/少なくともx /絶対に行わない」があり、neverjavadocがここにあります


144
を使用するのneverが最善かつ最も具体的な方法ですが、モックオブジェクト全体をチェックする必要がある場合は、verifyZeroInteractions(mockObject)またはも検討してくださいverifyNoMoreInteractions(mockObject)
ジェフボーマン

someMethodがプライベートの場合はどうしますか?
Sumit Kumar Saha

1
次に、最初の場所でそれをモックすることはできません(Mockitoを使用)。または、コードの所有権がある場合は、パッケージの可視性を緩和します。
Brice、

2
3.0.1以降verifyZeroInteractionsは非推奨です。 verifyNoInteractions 推奨される代替案です。このコメントの時点でのMockitoバージョンは3.3.3です
VKB

108

次のように、Mockito.verifyメソッドの2番目の引数を使用します。

verify(dependency, Mockito.times(0)).someMethod()


11
public static VerificationMode never(){return times(0); }
gbero 2017

3
never()は、よりも読みやすくはありませんtimes(0)。しかし、の存在はnever認知負荷を高め、mockitoシステムを理解し、使用方法を覚えるのを難しくします。だから本当にmockitoはnever彼らのAPIに含まれるべきではありません、それは精神的なコストの価値がありません。
BT

質問:このフォームsomeMethodは、0回someMethod呼び出されたことを確認しますか、それとも、引数なしで呼び出されたことがないことのみを確認しますか?
BT

@BT- someMethod引数なしの検証がゼロ回と呼ばれたことを検証すると思いますが、検証されていません。
ベルチン

18

従うべきより一般的なパターンとして、私は@Afterテストでブロックを使用する傾向があります:

@After
public void after() {
    verifyNoMoreInteractions(<your mock1>, <your mock2>...);
}

その後、テストは何呼び出す必要があるかのみを検証するために自由です。

また、「相互作用がない」ことを確認するのを忘れることが多かったのですが、後で、本来あるべきではないものが呼び出されていることに気づきました。

したがって、このパターンは、特に確認されていないすべての予期しない呼び出しをキャッチするのに役立ちます。


9
Mockitoのドキュメントでは、このパターンは悪用されるべきではないと述べています-「警告:多くのクラシックな期待実行検証モッキングを行った一部のユーザーは、すべてのテストメソッドでさえ、verifyNoMoreInteractions()を頻繁に使用する傾向があります。 ()をすべてのテストメソッドで使用することはお勧めしません。verifyNoMoreInteractions()は、相互作用テストツールキットからの便利なアサーションです。関連する場合にのみ使用してください。乱用すると、仕様が過剰になり、保守性が低下します。」こちらをご覧ください
Chadi

2
「適切な場合にのみ使用してください」。それは常に関連があると感じています。私はそのパターンを悪用とは思わない:私が言ったように、それは「本来あるべきではないものが呼び出されていた」ことを見つける。私にとって、それは検証の重要な部分です。何かが使用すべきではないリポジトリを呼び出している場合、それについて知りたいのです!を使用せずにそれを確認する別の方法がない限りverifyNoMoreInteractions?ここでの他の答えは、テスト作成者がこれらのチェックをリストすることを明示的に覚えていることに依存しています。それは、私の本ではエラーが発生しやすいからです。
David Lavender 2016年

2
私はこのコメントを見ましたが、その論法は説得力がないと感じました。これが推奨されない理由についてもっと読んでみたいです。
tobinibot 2016年

2
@tobinibotユニットテストのアイデアは契約を確認することです。ほとんどのコントラクトは通常、他のメソッドが呼び出された回数を含みませんが、既知のパラメーターを渡すと既知の応答が発生します。これ以上相互作用を使用しないことで、基本的には行ごとに実装を検証することになり、リファクタリングと実装が面倒になります。これは単体テストのポイントではありません。
Andrew T Finnell 2018

8

まず最初に、常にmockito staticをインポートする必要があります。これにより、コードがより読みやすく(直感的に)なります。

import static org.mockito.Mockito.*;

これを実現する方法は実際には数多くありますが、(間違いなく)を使用する方がクリーンです

verify(yourMock, times(0)).someMethod();

他のテストでは、このメソッドを使用して、次のように一定量の実行をアサートします。

verify(yourMock, times(5)).someMethod();

代替案は次のとおりです。

verify(yourMock, never()).someMethod();

または、特定のモックされたオブジェクトが実際にはまったく呼び出されないことを確認したい場合は、次のように使用できます。

verifyZeroInteractions(yourMock)

7

どちらverifyNoMoreInteractions()verifyZeroInteractions()方法は、内部で同じ実装などがあります。

public static transient void verifyNoMoreInteractions(Object mocks[])
{
    MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}

public static transient void verifyZeroInteractions(Object mocks[])
{
    MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}

したがって、モックオブジェクトまたはモックオブジェクトの配列でそれらのいずれかを使用して、モックオブジェクトを使用してメソッドが呼び出されていないことを確認できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.