En aquest tema, aprendrem com crear mocks utilitzant la biblioteca Mockito amb JUnit. Els mocks són objectes simulats que imiten el comportament d'objectes reals en un entorn controlat. Són especialment útils per aïllar el codi que estem provant de les seves dependències externes.

Objectius

  • Entendre què són els mocks i per què són útils.
  • Aprendre a crear mocks amb Mockito.
  • Veure exemples pràctics de com utilitzar mocks en tests.

Què és un Mock?

Un mock és un objecte que simula el comportament d'un altre objecte. En el context de les proves unitàries, els mocks permeten:

  • Aïllar el codi que estem provant de les seves dependències.
  • Simular diferents escenaris de prova.
  • Verificar que les interaccions amb les dependències es realitzen correctament.

Configuració de Mockito

Abans de començar a crear mocks, necessitem configurar Mockito en el nostre projecte. Si estàs utilitzant Maven, afegeix la següent dependència al teu pom.xml:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>3.11.2</version>
    <scope>test</scope>
</dependency>

Creant Mocks amb Mockito

Exemple Bàsic

A continuació, veurem un exemple bàsic de com crear un mock amb Mockito i utilitzar-lo en un test de JUnit.

import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

class UserServiceTest {

    @Test
    void testGetUserName() {
        // Crear un mock de la classe UserRepository
        UserRepository mockRepository = Mockito.mock(UserRepository.class);

        // Definir el comportament del mock
        when(mockRepository.findUserById(1)).thenReturn(new User(1, "John Doe"));

        // Utilitzar el mock en el test
        UserService userService = new UserService(mockRepository);
        String userName = userService.getUserName(1);

        // Verificar el resultat
        assertEquals("John Doe", userName);
    }
}

Explicació del Codi

  1. Crear el Mock: Utilitzem Mockito.mock(UserRepository.class) per crear un mock de la classe UserRepository.
  2. Definir el Comportament del Mock: Utilitzem when(mockRepository.findUserById(1)).thenReturn(new User(1, "John Doe")) per definir el comportament del mock. Això significa que quan es cridi al mètode findUserById(1), el mock retornarà un objecte User amb l'ID 1 i el nom "John Doe".
  3. Utilitzar el Mock: Passem el mock al constructor de UserService i utilitzem el servei per obtenir el nom de l'usuari.
  4. Verificar el Resultat: Utilitzem assertEquals("John Doe", userName) per verificar que el nom de l'usuari retornat és "John Doe".

Verificant Interaccions

A més de definir el comportament dels mocks, també podem verificar que les interaccions amb els mocks es realitzen correctament.

import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

class UserServiceTest {

    @Test
    void testGetUserName() {
        // Crear un mock de la classe UserRepository
        UserRepository mockRepository = Mockito.mock(UserRepository.class);

        // Definir el comportament del mock
        when(mockRepository.findUserById(1)).thenReturn(new User(1, "John Doe"));

        // Utilitzar el mock en el test
        UserService userService = new UserService(mockRepository);
        String userName = userService.getUserName(1);

        // Verificar el resultat
        assertEquals("John Doe", userName);

        // Verificar que el mètode findUserById(1) es va cridar exactament una vegada
        verify(mockRepository, times(1)).findUserById(1);
    }
}

Explicació del Codi

  1. Verificar Interaccions: Utilitzem verify(mockRepository, times(1)).findUserById(1) per verificar que el mètode findUserById(1) es va cridar exactament una vegada.

Exercici Pràctic

Exercici

Crea un test per a una classe OrderService que depèn d'una classe PaymentProcessor. Utilitza Mockito per crear un mock de PaymentProcessor i verifica que el mètode processPayment es crida amb els paràmetres correctes.

Solució

import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

class OrderServiceTest {

    @Test
    void testProcessOrder() {
        // Crear un mock de la classe PaymentProcessor
        PaymentProcessor mockProcessor = Mockito.mock(PaymentProcessor.class);

        // Definir el comportament del mock
        when(mockProcessor.processPayment(anyDouble())).thenReturn(true);

        // Utilitzar el mock en el test
        OrderService orderService = new OrderService(mockProcessor);
        boolean result = orderService.processOrder(100.0);

        // Verificar el resultat
        assertTrue(result);

        // Verificar que el mètode processPayment(100.0) es va cridar exactament una vegada
        verify(mockProcessor, times(1)).processPayment(100.0);
    }
}

Explicació del Codi

  1. Crear el Mock: Utilitzem Mockito.mock(PaymentProcessor.class) per crear un mock de la classe PaymentProcessor.
  2. Definir el Comportament del Mock: Utilitzem when(mockProcessor.processPayment(anyDouble())).thenReturn(true) per definir el comportament del mock. Això significa que quan es cridi al mètode processPayment amb qualsevol valor double, el mock retornarà true.
  3. Utilitzar el Mock: Passem el mock al constructor de OrderService i utilitzem el servei per processar una ordre.
  4. Verificar el Resultat: Utilitzem assertTrue(result) per verificar que el resultat és true.
  5. Verificar Interaccions: Utilitzem verify(mockProcessor, times(1)).processPayment(100.0) per verificar que el mètode processPayment(100.0) es va cridar exactament una vegada.

Conclusió

En aquest tema, hem après com crear mocks utilitzant Mockito i com utilitzar-los en tests de JUnit. Els mocks són una eina poderosa per aïllar el codi que estem provant de les seves dependències i verificar que les interaccions es realitzen correctament. En el següent tema, explorarem com verificar interaccions amb més detall.

© Copyright 2024. Tots els drets reservats