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
- Mocks: Objectes simulats que imiten el comportament d'objectes reals.
- Stubs: Objectes que retornen valors predefinits en resposta a trucades de mètodes.
- Spies: Objectes que permeten espiar les trucades de mètodes i verificar les interaccions.
- 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
:
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:
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
-
Creació del Mock:
UserRepository mockRepository = mock(UserRepository.class);
- Es crea un mock de la interfície
UserRepository
utilitzant Mockito.
- Es crea un mock de la interfície
-
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ètodefindById
amb el paràmetre1
.
- Es defineix el comportament del mock perquè retorni un objecte
-
Injecció del Mock:
UserService userService = new UserService(mockRepository);
- Es crea una instància de
UserService
passant el mock com a dependència.
- Es crea una instància de
-
Execució del Mètode a Provar:
User result = userService.getUserById(1);
- Es crida el mètode
getUserById
deUserService
.
- Es crida el mètode
-
Verificació del Resultat:
assertEquals("John Doe", result.getName());
- Es verifica que el resultat és el que s'esperava.
-
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àmetre1
.
- Es verifica que el mètode
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.
Curs de JUnit
Mòdul 1: Introducció a JUnit
Mòdul 2: Anotacions Bàsiques de JUnit
- Entenent @Test
- Utilitzant @Before i @After
- Utilitzant @BeforeClass i @AfterClass
- Ignorant Tests amb @Ignore
Mòdul 3: Assertions a JUnit
Mòdul 4: Tests Parametritzats
- Introducció als Tests Parametritzats
- Creant Tests Parametritzats
- Utilitzant @ParameterizedTest
- Tests Parametritzats Personalitzats
Mòdul 5: Suites de Test
Mòdul 6: Mocking amb JUnit
Mòdul 7: Funcions Avançades de JUnit
Mòdul 8: Millors Pràctiques i Consells
- Escrivint Tests Efectius
- Organitzant el Codi de Test
- Desenvolupament Guiat per Tests (TDD)
- Integració Contínua amb JUnit