フレームワークのモッキングにおけるモッキングとスパイ


131

フレームワークのモックでは、オブジェクトをモックしたり、スパイしたりできます。2つの違いは何ですか?また、いつどちらを使用するべきですか?

たとえばMockitoを見ると、スパイモックを使用して同様のことが行われていることがわかりますが、両者の違いわかりません



回答:


157

モックオブジェクトはモックされたクラスを完全に置き換え、記録された値またはデフォルト値を返します。「薄い空気」からモックを作成できます。これは、ユニットテスト中に主に使用されるものです。

スパイするときは、既存のオブジェクトを取得して、一部のメソッドのみを「置換」します。これは、巨大なクラスがあり、特定のメソッドのみをモックしたい場合(部分モック)に役立ちます。Mockitoのドキュメントを引用させてください。

実際のオブジェクトのスパイを作成できます。スパイを使用すると、実際のメソッドが呼び出されます(メソッドがスタブされない限り)。

実際のスパイは、たとえばレガシーコードを扱う場合など慎重に、そして時折使用する必要があります。

疑わしい場合はモックを使用してください。


1
ありがとうございました!それにより、より明確になります。だから、モックは嘲笑されている実際のオブジェクトに委譲したことがない、これまで、しかしスパイが行います。
Vivin Paliath、2012年

7
モックには「実際のオブジェクト」はありません。モックは最初から作成されます。
Carl Manaster、2012年

4
Mockitoが常にスパイの使用を警告する理由についての説明はありますか?彼らはモックを支持すると言っているようですが、その理由はよくわかりません。
2013年

9
私はわからないんだけど、多分理由は、彼らしている「Mockito」ではなく「Spyito」:D
typoerrpr

16

Mockitoは、部分的なモッキングは良い習慣ではないので、オブジェクト指向アーキテクチャを修正する必要があると警告しています。レガシーコードをテストするには、スパイ(または部分的なモッキング)が推奨されます


16

ここで例を使用して説明しようとします:

// 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を返しますが、実際のサイズが何であるかに関係なく。

簡単に言うと、実際のオブジェクトスパイしいくつかのメソッドスタブします


2

リファレンス:http : //javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/

モックオブジェクトを使用する場合、スタブでない場合のメソッドのデフォルトの動作は何もしません。単純なことは、そのvoidメソッドの場合、メソッドを呼び出しても何もしないか、戻り値のあるメソッドの場合、null、空、またはデフォルト値を返すことがあります。

もちろん、spyオブジェクトでは実際のメソッドであるため、メソッドをスタブしていない場合は、実際のメソッドの動作を呼び出します。メソッドを変更してモックしたい場合は、スタブする必要があります。


2

ダミーオブジェクトは渡されますが、実際には使用されません。通常、これらはパラメーターリストの入力に使用されます。

偽のオブジェクトは実際に機能する実装を持っていますが、通常はそれらを実稼働に適さないようにするいくつかのショートカットを取ります(メモリ内データベースが良い例です)。

スタブは、テスト中に行われた呼び出しに対する定型の回答を提供します。通常、テスト用にプログラムされたもの以外にはまったく応答しません。

スパイは、それらがどのように呼び出されたかに基づいていくつかの情報も記録するスタブです。この1つの形式は、送信されたメッセージの数を記録する電子メールサービスです。

モックとは、ここで話しているものです。事前にプログラムされたオブジェクトで、期待される呼び出しの仕様を形成します。

モックはマーティン・ファウラーによるスタブではありません


1

スパイには2つの定義があります。1つは、実際のメソッドが呼び出される場所、もう1つは、機能が呼び出されず、nullまたはnullに相当する値のみが返されるが、メソッドが呼び出され、それらの状態が記録された、通常、メソッドxがy回呼び出されたようなものです。


0

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