回答:
モックオブジェクトはモックされたクラスを完全に置き換え、記録された値またはデフォルト値を返します。「薄い空気」からモックを作成できます。これは、ユニットテスト中に主に使用されるものです。
スパイするときは、既存のオブジェクトを取得して、一部のメソッドのみを「置換」します。これは、巨大なクラスがあり、特定のメソッドのみをモックしたい場合(部分モック)に役立ちます。Mockitoのドキュメントを引用させてください。
実際のオブジェクトのスパイを作成できます。スパイを使用すると、実際のメソッドが呼び出されます(メソッドがスタブされない限り)。
実際のスパイは、たとえばレガシーコードを扱う場合など、慎重に、そして時折使用する必要があります。
疑わしい場合はモックを使用してください。
Mockitoは、部分的なモッキングは良い習慣ではないので、オブジェクト指向アーキテクチャを修正する必要があると警告しています。レガシーコードをテストするには、スパイ(または部分的なモッキング)が推奨されます。
ここで例を使用して説明しようとします:
// Difference between mocking, stubbing and spying
@Test
public void differenceBetweenMockingSpyingAndStubbing() {
List list = new ArrayList();
list.add("abc");
assertEquals(1, list.size());
List mockedList = spy(list);
when(mockedList.size()).thenReturn(10);
assertEquals(10, mockedList.size());
}
ここでは、最初の実際のオブジェクトがありました list
、1つの要素を追加し、サイズが1になると予測しました。
実際のオブジェクトをスパイします。つまり、どのメソッドをスタブするかを指示できます。だから我々は、我々はメソッドをスタブすることを宣言した- size()
にスパイオブジェクト 10を返しますが、実際のサイズが何であるかに関係なく。
簡単に言うと、実際のオブジェクトをスパイし 、いくつかのメソッドをスタブします。
リファレンス:http : //javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/
モックオブジェクトを使用する場合、スタブでない場合のメソッドのデフォルトの動作は何もしません。単純なことは、そのvoidメソッドの場合、メソッドを呼び出しても何もしないか、戻り値のあるメソッドの場合、null、空、またはデフォルト値を返すことがあります。
もちろん、spyオブジェクトでは実際のメソッドであるため、メソッドをスタブしていない場合は、実際のメソッドの動作を呼び出します。メソッドを変更してモックしたい場合は、スタブする必要があります。
ダミーオブジェクトは渡されますが、実際には使用されません。通常、これらはパラメーターリストの入力に使用されます。
偽のオブジェクトは実際に機能する実装を持っていますが、通常はそれらを実稼働に適さないようにするいくつかのショートカットを取ります(メモリ内データベースが良い例です)。
スタブは、テスト中に行われた呼び出しに対する定型の回答を提供します。通常、テスト用にプログラムされたもの以外にはまったく応答しません。
スパイは、それらがどのように呼び出されたかに基づいていくつかの情報も記録するスタブです。この1つの形式は、送信されたメッセージの数を記録する電子メールサービスです。
モックとは、ここで話しているものです。事前にプログラムされたオブジェクトで、期待される呼び出しの仕様を形成します。
Mockitoでは、モックオブジェクトのインスタンス変数にオブジェクトを割り当てても、モックオブジェクトには影響しません。
ただし、Spyの場合、Spyオブジェクトのインスタンス変数にオブジェクトを割り当てると、Spyはリアルタイムのオブジェクト変更のように動作するため、Spyオブジェクトに影響を与えます。
参考例としては
@RunWith(MockitoJUnitRunner.class)
public class MockSpyExampleTest {
@Mock
private List<String> mockList;
@Spy
private List<String> spyList = new ArrayList();
@Test
public void testMockList() {
//by default, calling the methods of mock object will do nothing
mockList.add("test");
assertNull(mockList.get(0));
}
@Test
public void testSpyList() {
//spy object will call the real method when not stub
spyList.add("test");
assertEquals("test", spyList.get(0));
}
}