Què és el Mocking?

El mocking és una tècnica utilitzada en les proves de programari per simular el comportament d'objectes reals. Aquesta tècnica és especialment útil quan es volen provar components de codi que depenen d'altres components que encara no estan disponibles, són difícils de configurar o tenen comportaments no deterministes (com ara serveis externs, bases de dades, etc.).

Conceptes Clau del Mocking

  1. Mocks: Objectes simulats que imiten el comportament d'objectes reals.
  2. Stubs: Objectes que retornen valors predefinits en resposta a trucades de mètodes.
  3. Spies: Objectes que permeten espiar les trucades de mètodes i verificar les interaccions.
  4. Fakes: Implementacions simplificades d'objectes reals que es poden utilitzar en proves.

Per què utilitzar Mocking?

  • Aïllament: Permet provar una unitat de codi aïllada de les seves dependències.
  • Control: Proporciona control sobre el comportament de les dependències.
  • Rendiment: Redueix el temps d'execució de les proves en eliminar la necessitat de configurar entorns complexos.
  • Fiabilitat: Evita la dependència de serveis externs que poden ser inestables o no disponibles.

Eines de Mocking

JUnit no inclou funcionalitats de mocking per defecte, però es pot utilitzar conjuntament amb biblioteques de mocking com Mockito. Mockito és una de les biblioteques de mocking més populars per a Java.

Instal·lació de Mockito

Per utilitzar Mockito amb JUnit, primer cal afegir la dependència de Mockito al projecte. Si utilitzes Maven, afegeix la següent dependència al fitxer pom.xml:

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

Si utilitzes Gradle, afegeix la següent línia al fitxer build.gradle:

testImplementation 'org.mockito:mockito-core:3.11.2'

Exemple Pràctic de Mocking amb Mockito

A continuació, es mostra un exemple pràctic de com utilitzar Mockito per crear un mock i verificar el seu comportament.

Escenari

Suposem que tenim una classe UserService que depèn d'una interfície UserRepository per obtenir informació dels usuaris.

public class UserService {
    private UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User getUserById(int id) {
        return userRepository.findById(id);
    }
}

La interfície UserRepository és la següent:

public interface UserRepository {
    User findById(int id);
}

Creant un Mock amb Mockito

A continuació, es mostra com crear un mock de UserRepository i utilitzar-lo en una prova de UserService.

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

public class UserServiceTest {

    @Test
    public void testGetUserById() {
        // Crear un mock de UserRepository
        UserRepository mockRepository = mock(UserRepository.class);

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

        // Crear una instància de UserService amb el mock
        UserService userService = new UserService(mockRepository);

        // Executar el mètode a provar
        User result = userService.getUserById(1);

        // Verificar el resultat
        assertEquals("John Doe", result.getName());

        // Verificar que el mètode findById va ser cridat una vegada amb el paràmetre 1
        verify(mockRepository, times(1)).findById(1);
    }
}

Explicació del Codi

  1. Creació del Mock: UserRepository mockRepository = mock(UserRepository.class);

    • Es crea un mock de la interfície UserRepository utilitzant Mockito.
  2. Definició del Comportament: when(mockRepository.findById(1)).thenReturn(mockUser);

    • Es defineix el comportament del mock perquè retorni un objecte User quan es cridi el mètode findById amb el paràmetre 1.
  3. Injecció del Mock: UserService userService = new UserService(mockRepository);

    • Es crea una instància de UserService passant el mock com a dependència.
  4. Execució del Mètode a Provar: User result = userService.getUserById(1);

    • Es crida el mètode getUserById de UserService.
  5. Verificació del Resultat: assertEquals("John Doe", result.getName());

    • Es verifica que el resultat és el que s'esperava.
  6. Verificació de les Interaccions: verify(mockRepository, times(1)).findById(1);

    • Es verifica que el mètode findById del mock va ser cridat una vegada amb el paràmetre 1.

Conclusió

El mocking és una tècnica poderosa que permet aïllar i provar unitats de codi de manera efectiva. Utilitzant biblioteques com Mockito, es poden crear mocks, definir el seu comportament i verificar les interaccions de manera senzilla. En els següents temes, explorarem com utilitzar Mockito amb JUnit per crear mocks més avançats i verificar interaccions complexes.


En el següent tema, "Utilitzant Mockito amb JUnit", aprofundirem en com integrar Mockito amb JUnit per millorar les nostres proves unitàries.

© Copyright 2024. Tots els drets reservats