En aquest tema, aprendrem com verificar les interaccions entre els mocks i els objectes reals utilitzant Mockito amb JUnit. La verificació d'interaccions és crucial per assegurar-nos que els nostres mocks es comporten com esperem durant les proves.

Objectius

  • Entendre la importància de verificar interaccions.
  • Aprendre a utilitzar les funcions de verificació de Mockito.
  • Veure exemples pràctics de verificació d'interaccions.

Importància de Verificar Interaccions

Quan fem servir mocks en les nostres proves, no només ens interessa el resultat final, sinó també com s'ha arribat a aquest resultat. Verificar les interaccions ens permet assegurar-nos que els mètodes dels mocks s'han cridat amb els arguments correctes i en l'ordre esperat.

Funcions de Verificació de Mockito

Mockito proporciona diverses funcions per verificar interaccions. Les més comunes són:

  • verify(mock): Verifica que un mètode del mock s'ha cridat.
  • verify(mock, times(n)): Verifica que un mètode del mock s'ha cridat exactament n vegades.
  • verify(mock, never()): Verifica que un mètode del mock no s'ha cridat mai.
  • verify(mock, atLeast(n)): Verifica que un mètode del mock s'ha cridat almenys n vegades.
  • verify(mock, atMost(n)): Verifica que un mètode del mock s'ha cridat com a màxim n vegades.

Exemple Pràctic

Escenari

Suposem que tenim una classe UserService que depèn d'una interfície UserRepository per obtenir informació dels usuaris. Volem verificar que el mètode findUserById de UserRepository s'ha cridat correctament.

Codi

// UserService.java
public class UserService {
    private UserRepository userRepository;

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

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

// UserRepository.java
public interface UserRepository {
    User findUserById(int id);
}

// UserServiceTest.java
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class UserServiceTest {
    private UserRepository userRepository;
    private UserService userService;

    @BeforeEach
    public void setUp() {
        userRepository = mock(UserRepository.class);
        userService = new UserService(userRepository);
    }

    @Test
    public void testGetUserById() {
        User user = new User(1, "John Doe");
        when(userRepository.findUserById(1)).thenReturn(user);

        User result = userService.getUserById(1);

        assertEquals(user, result);
        verify(userRepository).findUserById(1); // Verifica que el mètode s'ha cridat una vegada
    }
}

Explicació del Codi

  1. Mocking: Utilitzem mock(UserRepository.class) per crear un mock de UserRepository.
  2. Configuració: Utilitzem when(userRepository.findUserById(1)).thenReturn(user) per definir el comportament del mock.
  3. Verificació: Utilitzem verify(userRepository).findUserById(1) per verificar que el mètode findUserById s'ha cridat amb l'argument 1.

Exercicis Pràctics

Exercici 1

Crea una classe OrderService que depengui d'una interfície OrderRepository. Escriu una prova que verifiqui que el mètode saveOrder de OrderRepository s'ha cridat exactament una vegada quan es guarda una comanda.

Solució

// OrderService.java
public class OrderService {
    private OrderRepository orderRepository;

    public OrderService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }

    public void saveOrder(Order order) {
        orderRepository.saveOrder(order);
    }
}

// OrderRepository.java
public interface OrderRepository {
    void saveOrder(Order order);
}

// OrderServiceTest.java
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class OrderServiceTest {
    private OrderRepository orderRepository;
    private OrderService orderService;

    @BeforeEach
    public void setUp() {
        orderRepository = mock(OrderRepository.class);
        orderService = new OrderService(orderRepository);
    }

    @Test
    public void testSaveOrder() {
        Order order = new Order(1, "Product A");

        orderService.saveOrder(order);

        verify(orderRepository).saveOrder(order); // Verifica que el mètode s'ha cridat una vegada
    }
}

Exercici 2

Modifica la prova anterior per verificar que el mètode saveOrder no s'ha cridat mai quan es passa una comanda nul·la.

Solució

@Test
public void testSaveOrderWithNull() {
    orderService.saveOrder(null);

    verify(orderRepository, never()).saveOrder(any(Order.class)); // Verifica que el mètode no s'ha cridat mai
}

Conclusió

La verificació d'interaccions és una part essencial de les proves amb mocks. Ens permet assegurar-nos que els nostres mocks es comporten com esperem i que els mètodes s'han cridat amb els arguments correctes. Amb les funcions de verificació de Mockito, podem escriure proves més robustes i fiables.

© Copyright 2024. Tots els drets reservats