モックフレームワークでは、オブジェクトをモックしたり、スパイしたりできます。この2つの違いは何ですか?また、どちらを使用するのか、いつ使用するのか、どちらを使用する必要がありますか?
たとえば、 Mockitoを見ると、スパイとモックを使用して同様のことが行われていることがわかりますが、この2つの違いについてはよくわかりません。
モックフレームワークでは、オブジェクトをモックしたり、スパイしたりできます。この2つの違いは何ですか?また、どちらを使用するのか、いつ使用するのか、どちらを使用する必要がありますか?
たとえば、 Mockitoを見ると、スパイとモックを使用して同様のことが行われていることがわかりますが、この2つの違いについてはよくわかりません。
モックオブジェクトはモッククラスを完全に置き換え、記録された値またはデフォルト値を返します。「薄い空気」からモックを作成できます。これは、ユニットテスト中に主に使用されるものです。
スパイするときは、既存のオブジェクトを取得し、一部のメソッドのみを「置換」します。これは、巨大なクラスがあり、特定のメソッドのみをモックしたい場合(部分的なモック)に役立ちます。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と予想しました。
実際のオブジェクトをスパイします。つまり、どのメソッドをスタブするかを指示できます。そこで、実際のサイズに関係なく、10を返すスパイオブジェクトに対してsize()
メソッドをスタブ化することを宣言しました。
一言で言えば、実際のオブジェクトをスパイ し、いくつかのメソッドをスタブします。
Mockitoは、部分的なモックは良い習慣ではないので、オブジェクト指向アーキテクチャを修正する必要があると警告しています。レガシーコードをテストするには、スパイ(または部分的なモック)をお勧めします。
Mockitoでは、モックオブジェクトのインスタンス変数にオブジェクトを割り当てても、モックオブジェクトには影響しません。
ただし、Spyの場合、Spy Objectのインスタンス変数にオブジェクトを割り当てると、Spyはリアルタイムのオブジェクト変更のように機能するため、SpyObjectに影響を与えます。
参考例としては
@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));
}
}
マーティン・ファウラーによるモックはスタブではありません:
ダミーオブジェクトは渡されますが、実際に使用されることはありません。通常、これらはパラメータリストを埋めるために使用されます。
偽のオブジェクトには実際に機能する実装がありますが、通常はショートカットを使用するため、本番環境には適していません(インメモリデータベースが良い例です)。
スタブは、テスト中に行われた呼び出しに対して定型の応答を提供しますが、通常、テスト用にプログラムされたもの以外にはまったく応答しません。
スパイはスタブであり、呼び出された方法に基づいていくつかの情報も記録します。これの1つの形式は、送信されたメッセージの数を記録する電子メールサービスである可能性があります。
ここで話しているのはモックです。オブジェクトは、受信することが期待される呼び出しの仕様を形成する期待値で事前にプログラムされています。
参照: http: //javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/
モックオブジェクトを使用する場合、スタブでない場合のメソッドのデフォルトの動作は何もしません。単純な意味は、voidメソッドの場合、メソッドを呼び出したときに何も実行しないか、戻り値のあるメソッドの場合、null、空、またはデフォルト値を返す可能性があることを意味します。
もちろん、スパイオブジェクトでは、これは実際のメソッドであるため、メソッドをスタブ化していない場合は、実際のメソッドの動作を呼び出します。メソッドを変更してモックしたい場合は、スタブする必要があります。
スパイには2つの定義があります。1つは、実際のメソッドが呼び出される場所であり、もう1つは、機能が呼び出されず、nullまたはnullの同等の値のみが返されるが、メソッドが呼び出され、メソッドxがy回呼び出されたように、状態が記録された場所です。