web-dev-qa-db-ja.com

Mockito - doReturn()とwhen()の違い

私は現在、私のControllerメソッドをテストしたいSpring MVCアプリケーションで私のサービスレイヤオブジェクトをモックするためにMockitoを使用しているところです。しかし、私がMockitoの詳細について読んできたように、メソッドdoReturn(...).when(...)when(...).thenReturn(...)と同等であることがわかりました。それで、私の質問は、同じことをする2つのメソッドを持つことのポイントは何ですか、またはdoReturn(...).when(...)when(...).thenReturn(...)の間の微妙な違いは何ですか?

任意の助けがいただければ幸いです。

145
blackpanther

スタブの2つの構文はほぼ同じです。ただし、スタブにはalwaysdoReturn/whenを使用できます。しかし、あなたができないwhen/thenReturnを使うケースがあります。空のメソッドをスタブすることはそのようなものです。その他には、Mockitoスパイとの使用、および同じ方法を複数回スタブすることが含まれます。

when/thenReturnから得られることの1つ、doReturn/whenはそうではないことですが、返される値をコンパイル時に型チェックすることです。ただし、これはほとんど価値がないと思います。型が間違っている場合は、テストを実行するとすぐにわかります。

doReturn/whenのみを使用することを強くお勧めします。 2つの構文を習得しても意味がありません。

あなたは私の答えを参照することをお勧めします Forming Mockito "grammars" - 非常に密接に関連した質問に対するより詳細な答え。

184

@Spyでアノテーションが付けられた)モックの代わりに(@Mockでアノテーションが付けられた)スパイオブジェクトを使用する場合、どちらのアプローチも異なる動作をします。

  • when(...) thenReturn(...)実際のメソッドを呼び出す指定された値が返される直前に。そのため、呼び出されたメソッドが例外を投げた場合は、それを処理したりモックしたりする必要があります。もちろん、結果はまだ得られます(thenReturn(...)で定義したもの)。

  • doReturn(...) when(...)メソッドをまったく呼び出さない

例:

public class MyClass {
     protected String methodToBeTested() {
           return anotherMethodInClass();
     }

     protected String anotherMethodInClass() {
          throw new NullPointerException();
     }
}

テスト:

@Spy
private MyClass myClass;

// ...

// would work fine
doReturn("test").when(myClass).anotherMethodInClass();

// would throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");
146
akcasoy

Mockitoのjavadocは、Mockito.when(Object)を使用できない場合に、doReturn()の代わりにwhen()を使用する理由を説明しているようです。

Mockito.when(Object)は引数の型が安全で読みやすいため(特に連続した呼び出しをスタブする場合)、スタブには常に推奨されることに注意してください。

DoReturn()が便利になることがまれにあります。

1。実際のオブジェクトをスパイし、スパイ上で実際のメソッドを呼び出すと副作用が生じる

List list = new LinkedList(); List spy = spy(list);

//不可能:実際のメソッドが呼び出されるため、spy.get(0)はIndexOutOfBoundsExceptionをスローします(リストはまだ空です)。

when(spy.get(0)).thenReturn("foo");

//スタブを作成するにはdoReturn()を使用する必要があります。doReturn("foo").when(spy).get(0);

2。前回の例外スタブを上書きする:

when(mock.foo()).thenThrow(new RuntimeException());

//不可能:exception-stubbed foo()メソッドが呼び出されるのでRuntimeExceptionがスローされるwhen(mock.foo()).thenReturn("bar");

//スタブにはdoReturn()を使用する必要があります。

doReturn("bar").when(mock).foo();上のシナリオはMockitoの洗練された構文のトレードオフを示しています。ただし、シナリオは非常にまれです。スパイは散発的であるべきであり、例外スタブをオーバーライドすることは非常にまれです。言うまでもなく、一般的にスタブをオーバーライドすることは、あまりにも多くのスタブを指摘する潜在的なコード臭いです。

9
user2493028

後者の方法はvoidを返すモックのメソッドに使われます。

たとえば、こちらをご覧ください。 mockitoでメソッドを無効にするためのモックの作成方法

5
vikingsteve

続き この答え 、例えば最初に呼ばれた時、二度目に呼ばれた時などにあなたのメソッドが異なる値を返すようにしたい場合、あなたは値を渡すことができます。

PowerMockito.doReturn(false, false, true).when(SomeClass.class, "SomeMethod", Matchers.any(SomeClass.class));

そのため、同じテストケースでメソッドが呼び出されるとfalseが返され、次にfalseが返され、最後にtrueが返されます。

5
AZ_