Mocking de méthodes privées utilisant PowerMock

Se moquer des méthodes privées à l'aide de PowerMock

1. Vue d'ensemble

L'un des défis des tests unitaires est de se moquer des méthodes privées.

Dans ce tutoriel, nous allons découvrir comment nous pouvons y parvenir en utilisant la bibliothèquePowerMock - qui est prise en charge par JUnit et TestNG.

PowerMock integrates with mocking frameworks like EasyMock and Mockito and is meant to add additional functionality to these – such as mocking private methods, final classes, and final methods, etc.

Pour ce faire, il s’appuie sur la manipulation de bytecode et sur un chargeur de classes entièrement séparé.

2. Dépendances Maven

Tout d'abord, ajoutons les dépendances requises pour utiliser PowerMock avec Mockito et JUnit dans nospom.xml:


    org.powermock
    powermock-module-junit4
    1.7.3
    test


    org.powermock
    powermock-api-mockito2
    1.7.3
    test

Les dernières versions peuvent être vérifiéeshere ethere.

3. Exemple

Commençons par un exemple deLuckyNumberGenerator. Cette classe a une seule méthode publique pour générer un nombre chanceux:

public int getLuckyNumber(String name) {
    saveIntoDatabase(name);
    if (name == null) {
        return getDefaultLuckyNumber();
    }
    return getComputedLuckyNumber(name.length());
}

4. Variations dans la moquerie des méthodes privées

Pour un test unitaire exhaustif de la méthode, nous devrons nous moquer des méthodes privées.

4.1. Méthode sans argument mais avec valeur de retour

À titre d'exemple simple, simulons le comportement d'une méthode privée sans arguments et forçons-la à renvoyer la valeur souhaitée:

LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());

when(mock, "getDefaultLuckyNumber").thenReturn(300);

Dans ce cas, nous nous moquons de la méthode privéegetDefaultLuckyNumber et lui faisons renvoyer une valeur de 300.

4.2. Méthode avec argument et valeur de retour

Ensuite, simulons le comportement d'une méthode privée avec un argument et forçons-la à renvoyer la valeur souhaitée:

LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());

doReturn(1).when(mock, "getComputedLuckyNumber", ArgumentMatchers.anyInt());

Dans ce cas, nous moquons la méthode privée et la renvoyons 1.

Notez que nous ne nous soucions pas de l'argument d'entrée et utilisonsArgumentMatchers.anyInt() comme caractère générique.

4.3. Vérification de l'invocation d'une méthode

Notre stratégie finale consiste à utiliser PowerMock pour vérifier l’appel d’une méthode privée:

LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());
int result = mock.getLuckyNumber("Tyranosorous");

verifyPrivate(mock).invoke("saveIntoDatabase", ArgumentMatchers.anyString());

5. Un mot d'avertissement

Enfin, bien que les méthodes privées puissent être testées à l'aide de PowerMock,we must be extra cautious while using this technique.

Étant donné que l'objectif de nos tests est de valider le comportement d'une classe, nous devons éviter de modifier le comportement interne de la classe pendant les tests unitaires.

Les techniques de moquerie doivent être appliquées aux dépendances externes de la classe et non à la classe elle-même.

S'il est essentiel de se moquer des méthodes privées pour tester nos classes, cela indique généralement une mauvaise conception.

6. Conclusion

Dans cet article rapide, nous avons montré comment utiliser PowerMock pour étendre la capacité de Mockito à se moquer et à vérifier les méthodes privées dans la classe testée.

Le code source de ce tutoriel peut être trouvéover on GitHub.