Mocks et stubs dans les tests unitaires

Introduction aux tests en Java

Maria Milusheva

Senior Software Engineer

Motivation : dépendances

Rappelez-vous le flux de dépendances vu précédemment : l'app d'échange de devises dépend du serveur bancaire : Un graphe Mermaid du flux de dépendances dans la démo bancaire

Impossible de vérifier les calculs car les taux de change sont par nature imprévisibles.

Introduction aux tests en Java

Gestion des dépendances en test

Mocking : création d'objets ou de comportements simulés pour des objets réels difficiles à utiliser en test, afin de tester sans dépendances externes.


import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Exemple de mocking

Introduction aux tests en Java

Mocking

  • Mock = comme une doublure au théâtre, qui joue l'objet réel uniquement pour le test

Reprenez la leçon précédente :

public double convertEuroTo(String currency, double amount) {
    double rate = this.bank.getRateEuroTo(currency);
    return amount * rate;
}

➡ Créer un objet prédictible pour EuropeanCentralBankServer pour les tests

Introduction aux tests en Java

Mocking : change de devises

Voici comment tester avec des mocks :

@Test
void convert_returnsExpectedValue() {
    EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
    ExchangeApp exchangeApp = new ExchangeApp(bank);

// Il faut programmer le mock pour qu'il réponde when(bank.getRateEuroTo("USD")).thenReturn(1.1);
// Appelle getRateEuroTo sur le mock, renvoyant notre valeur programmée double result = exchangeApp.convertEuroTo("USD", 1000); assertEquals(1100, result); // On peut maintenant vérifier une valeur exacte }
Introduction aux tests en Java

Erreur fréquente

N'oubliez jamais de programmer vos mocks :

@Test
void convert_returnsExpectedValue() {
    EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
    ExchangeApp exchangeApp = new ExchangeApp(bank);

    // Pas de programmation du mock : l'objet bank simulé ne sait pas répondre à getRateEuroTo
    double result = exchangeApp.convertEuroTo("USD", 1000);

    assertEquals(1100, result); // Échouera faute de configuration du mock
}
Introduction aux tests en Java

Stubbing

Le test échoue avec :

org.opentest4j.AssertionFailedError: 
Expected :1100.0
Actual   :0.0

Programmer un mock s'appelle le stubbing.

Stubbing : fournir des réponses minimales et prédéfinies aux appels pendant le test, sans répondre au-delà de ce qui est programmé.

Introduction aux tests en Java

Exceptions avec Mockito

Mockito peut aussi simuler des scénarios d'erreur :

EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
ExchangeApp exchangeApp = new ExchangeApp(bank);
// Au lieu de thenReturn(), utiliser thenThrow()
when(bank.getRateEuroTo("USD"))
        .thenThrow(new RuntimeException("Bank server unavailable."));

exchangeApp.convertEuroTo("USD", 1000); // getRateEuroTo lèvera une exception
Introduction aux tests en Java

Passons à la pratique !

Introduction aux tests en Java

Preparing Video For Download...