163 votes

Moquerie et espionnage dans les cadres de moquerie

Dans les frameworks de mocking, vous pouvez simuler un objet ou espionner sur elle. Quelle est la différence entre les deux et quand devrais-je utiliser l'un plutôt que l'autre ?

Regarder Mockito par exemple, je vois que des choses similaires sont réalisées à l'aide des éléments suivants espions y mocks mais je ne suis pas sûr de la distinction entre les deux.

197voto

Tomasz Nurkiewicz Points 140462

L'objet fantaisie remplace entièrement la classe fantaisie et renvoie des valeurs enregistrées ou par défaut. Vous pouvez créer un objet fantaisie à partir de "l'air libre". C'est ce qui est principalement utilisé lors des tests unitaires.

Lors de l'espionnage, vous prenez un objet existant et ne "remplacez" que certaines méthodes. C'est utile lorsque vous avez une classe énorme et que vous ne voulez simuler que certaines méthodes (simulacre partiel). Permettez-moi de citer Documentation sur Mockito :

Vous pouvez créer des espions à partir d'objets réels. Lorsque vous utilisez l'espion, le réel sont appelées (à moins qu'une méthode n'ait été stubée).

Il faut utiliser de vrais espions soigneusement et occasionnellement par exemple lorsqu'il s'agit d'un code hérité.

En cas de doute, utilisez les mocks.

27voto

user2775185 Points 459

Je vais essayer de vous expliquer à l'aide d'un exemple :

// 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 un objet initial réel list dans lequel nous avons ajouté un élément et attendu que la taille soit de un.

Nous espionner objet réel, ce qui signifie que nous pouvons indiquer la méthode à utiliser. tronqué . Donc nous avons déclaré que nous avons stubé la méthode - size() sur objet espion qui renverra 10, quelle que soit la taille réelle.

En bref, vous allez espionner objet réel y talon certaines des méthodes .

16voto

user2547705 Points 11

Mockito prévient que le mocking partiel n'est pas une bonne pratique et que vous devriez revoir votre architecture orientée objet. Espionner (ou un mocking partiel) est recommandé pour tester les éléments suivants code hérité .

8voto

Mohsen Points 602

Sur la base de Les mocks ne sont pas des stubs par Martin Fowler :

Dummy Les objets circulent mais ne sont jamais utilisés. En général, ils sont juste utilisés pour remplir les listes de paramètres.

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

Stubs fournissent des réponses toutes faites aux appels effectués pendant le test, et ne répondent généralement pas du tout à ce qui n'est pas programmé pour le test.

Espions sont des stubs qui enregistrent également certaines informations basées sur la façon dont ils ont été appelés. Il peut s'agir par exemple d'un service de messagerie électronique qui enregistre le nombre de messages qu'il a envoyés.

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

7voto

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

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

Voici un exemple de référence

@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));
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X