Mocking vs.Spying dans des frameworks moqueurs

131

Dans les frameworks moqueurs, vous pouvez vous moquer d' un objet ou l' espionner . Quelle est la différence entre les deux et quand devrais-je / devrais-je utiliser l'un par rapport à l'autre?

En regardant Mockito , par exemple, je vois des choses similaires se faire en utilisant des espions et des moqueurs , mais je ne suis pas sûr de la distinction entre les deux.

Vivin Paliath
la source

Réponses:

157

L'objet fictif remplace entièrement la classe simulée, renvoyant les valeurs enregistrées ou par défaut. Vous pouvez créer des simulations à partir de "l'air mince". C'est ce qui est le plus souvent utilisé lors des tests unitaires.

Lors de l'espionnage, vous prenez un objet existant et ne "remplacez" que certaines méthodes. Ceci est utile lorsque vous avez une classe énorme et que vous ne voulez vous moquer que de certaines méthodes (moquage partiel). Permettez-moi de citer la documentation Mockito :

Vous pouvez créer des espions d'objets réels. Lorsque vous utilisez l'espion, les méthodes réelles sont appelées (sauf si une méthode a été stubbée).

Les vrais espions doivent être utilisés avec précaution et occasionnellement , par exemple lorsqu'il s'agit de code hérité.

En cas de doute, utilisez des simulacres.

Tomasz Nurkiewicz
la source
1
Je vous remercie! Cela rend les choses beaucoup plus claires. Donc , se moque jamais déléguer à l'objet réel se moque jamais , mais les espions font.
Vivin Paliath
7
Les simulacres n'ont pas d '"objet réel" - le simulacre est créé ab initio.
Carl Manaster
4
Une explication pour laquelle Mockito met en garde contre l'utilisation d'espions tout le temps? Je vois qu'ils disent de favoriser les moqueries, mais je ne sais pas pourquoi.
Matt
9
Je ne suis pas sûr, mais peut-être parce qu'ils sont "Mockito" et non "Spyito": D
typoerrpr
16

Mockito avertit que la moquerie partielle n'est pas une bonne pratique et que vous devez réviser votre architecture orientée objet. Il est recommandé d' espionner (ou de se moquer partiellement) pour tester le code hérité .

Suelmar Zanetti
la source
16

Je vais essayer d'expliquer en utilisant un exemple ici:

// 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());
}

Ici, nous avions l'objet réel initial list, dans lequel nous avons ajouté un élément et la taille attendue en être un.

Nous espionnons un objet réel, ce qui signifie que nous pouvons indiquer quelle méthode doit être stubbée . Nous avons donc déclaré que nous avons stubbed la méthode - size()sur un objet espion qui retournera 10, quelle que soit la taille réelle.

En un mot, vous espionnerez un objet réel et en supprimerez certaines des méthodes .

user2775185
la source
2

Référence: http://javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/

Lors de l'utilisation d'objets fictifs, le comportement par défaut de la méthode lorsqu'elle n'est pas stub est de ne rien faire. Simple signifie que si c'est une méthode void, alors il ne fera rien lorsque vous appelez la méthode ou si c'est une méthode avec un retour, il peut retourner null, vide ou la valeur par défaut.

Dans les objets espions, bien sûr, puisqu'il s'agit d'une méthode réelle, lorsque vous ne stubbing pas la méthode, elle appellera le comportement réel de la méthode. Si vous souhaitez modifier et vous moquer de la méthode, vous devez la stuber.

Jerry C.
la source
2

Des objets factices sont transmis mais jamais réellement utilisés. Habituellement, ils sont simplement utilisés pour remplir les listes de paramètres.

Les faux objets ont en fait des implémentations fonctionnelles, mais prennent généralement un raccourci qui les rend non adaptés à la production (une base de données en mémoire est un bon exemple).

Les stubs fournissent des réponses prédéfinies aux appels effectués pendant le test, ne répondant généralement pas du tout à quoi que ce soit en dehors de ce qui est programmé pour le test.

Les espions sont des stubs qui enregistrent également certaines informations en fonction de la façon dont ils ont été appelés. Une forme de ceci pourrait être un service de messagerie qui enregistre le nombre de messages envoyés.

Les simulacres sont ce dont nous parlons ici: des objets préprogrammés avec des attentes qui forment une spécification des appels qu'ils sont censés recevoir.

Les mocks ne sont pas des talons par Martin Fowler

Mohsen
la source
1

Les espions ont deux définitions. L'un, est l'endroit où la méthode réelle est appelée, un autre où, aucune fonctionnalité n'est appelée et seules les valeurs équivalentes nulles ou nulles sont renvoyées, mais les méthodes ont été appelées et leur état a été enregistré, généralement comme la méthode x a été appelée y fois.

John Heilman
la source
0

Dans Mockito, si vous affectez un objet à la variable d'instance de Mock Object, cela n'affecte pas l'objet Mock.

Mais dans le cas de Spy, si vous affectez un objet à la variable d'instance de Spy Object, cela affecte alors Spy Object car Spy agit comme une modification d'objet en temps réel.

Pour un exemple de référence sont

@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));
    }
}
Yasir Shabbir Choudhary
la source