Comme nous l'avons vu précédemment, les tests unitaires locaux s'exécutent très rapidement, car ils utilisent la JVM de votre ordinateur. En d'autres termes, il n'est pas nécessaire de démarrer l'émulateur ou de brancher un équipement pour dérouler ces tests.
Toutefois, il est possible que vous ayez besoin d'accéder à une dépendance spécifique d'Android, par exemple la classe Context. Dans ce cas, vous allez perdre tout le bénéfice de rapidité d'exécution d'un test local. Et ce pour accéder à une seule méthode, ce qui est assez frustrant.
Heureusement, il existe des bouchons, ou mocks en anglais, qui permettent de résoudre ce problème. Je vous présente Mockito, que nous allons étudier dans ce chapitre.
Découvrez Mockito
Mockito est un framework qui vous permet de bouchonner certaines parties de votre code. Dit autrement, il vous permet de simuler l'appel à certaines méthodes, et de décider à l'avance de la valeur retournée.
Cela ne vous semble pas très clair ? Je vais vous donner un exemple.
Nous souhaitons faire évoluer CoinCoinTracker en ajoutant une nouvelle fonctionnalité. Cette fonctionnalité permet de protéger l'accès au contenu du porte-monnaie virtuel à l'aide d'une empreinte digitale et d'un mot de passe. Eh oui, l'application est ultra-sécurisée !
Pour récupérer le solde du porte-monnaie, un écran est donc présenté à l'utilisateur. Cet écran lui demande de saisir son mot de passe et de valider son empreinte digitale. Cette opération permet de récupérer un jeton, ou token, en anglais, qui sera utilisé pour récupérer le solde du porte-monnaie.
Le problème, c'est qu'il est désormais nécessaire de lancer l'application et d'intervenir manuellement pour récupérer ce jeton. Et c'est là que Mockito intervient : il va nous permettre de simuler cette partie, et nous renvoyer directement un jeton. Et le tout localement, sans avoir à lancer l'émulateur. Elle n'est pas belle la vie ?
Utilisez Mockito
Installez Mockito
Pour installer Mockito, n'hésitez pas à consulter les instructions sur la page officielle. La capture d'écran ci-dessous vous résume les trois étapes principales.
Commencez par ouvrir le fichier build.gradle situé dans le module app (1). Ensuite, ajoutez la ligne suivante, dans la section dependencies (2) :
testImplementation "org.mockito:mockito-core:3.+"
Enfin, cliquez sur le bouton Sync Now (3). N'oubliez surtout pas cette étape, car sinon le framework Mockito ne sera pas installé !
Créez une nouvelle activité
Pour les besoins de notre test, créez une nouvelle activité nommée AuthActivity. Ajoutez la méthode suivante :
public String getUserToken() { SharedPreferences prefs = getSharedPreferences("UserToken", MODE_PRIVATE); // Fetches the token, does a lot of things, then... return "IncredibleToken"; }
Écrivez un nouveau test
Ouvrez le fichier WalletUnitTest et créez un nouveau test nommé testWalletContent(). Ce test instancie l'activité AuthActivity créée précédemment, et appelle la méthode getUserToken() :
@Test public void testWalletContent() throws Exception { AuthActivity authActivity = new AuthActivity(); String token = authActivity.getUserToken(); // Test token }
Lancez le test. Que constatez-vous ? Normalement, vous devriez voir apparaître l'erreur suivante :
L'API SharedPreferences repose sur la classe Context. Or, cette classe n'est disponible qu'au sein du système Android. Sachant que le test est exécuté localement sur la JVM, nous n'y avons pas accès. D'où l'erreur constatée, qui stipule que la méthode getSharedPreferences() n'est pas bouchonnée.
Créez le bouchon avec Mockito
L'utilisation de Mockito est très intuitive. Reprenez le test getWalletContent(), puis remplacez la ligne d'instanciation de la classe AuthActivity par celle-ci :
AuthActivity authActivity = mock(AuthActivity.class);
Pensez au passage à importer la classe Mockito pour avoir accès à ses méthodes, en ajoutant en haut du fichier :
import static org.mockito.Mockito.*;
Maintenant, ajoutez la ligne suivante :
when(authActivity.getUserToken()).thenReturn("FakeToken");
Cette ligne de code se lit très naturellement : "lorsque la méthode getUserToken() est appelée, alors renvoyer directement la chaîne de caractères FakeToken". Le code de la méthode de test doit ressembler à ceci :
public void testWalletContent() throws Exception { AuthActivity authActivity = mock(AuthActivity.class); when(authActivity.getUserToken()).thenReturn("FakeToken"); String token = authActivity.getUserToken(); // Test token }
Relancez le test : l'erreur a disparu, bravo !
Vous pouvez ainsi bouchonner toutes les méthodes qui vous intéressent, et décider vous-même de la valeur à renvoyer. Sachez qu'il existe toutefois une limitation à l'utilisation de Mockito : il n'est pas possible de bouchonner des méthodes statiques ou privées.
Récapitulons en vidéo
En résumé
Mockito est un framework qui vous permet de simuler l'appel à certaines méthodes, et de décider à l'avance de la valeur retournée.
Mockito permet de conserver la rapidité des tests locaux tout en bouchonnant l’appel aux fonctions ayant une dépendance spécifique d’Android.
Vous ne pouvez pas simuler l’appel à des fonctions statiques ou privées.
Vous savez maintenant comment bouchonner vos méthodes grâce à Mockito. Suivez-moi dans le dernier chapitre de ce cours pour aller encore plus loin !