· Jose Ramón Bogarin · Tutorial · 4 min read
Pruebas unitarias
¿Realmente son necesarias hacer pruebas unitarias? son perdida de tiempo? ¿hace tener el doble de tiempo en la entrega?.
Descripción General
Las pruebas unitarias son una práctica esencial en el desarrollo de software, y aunque puede parecer que agregan tiempo al proceso de desarrollo, en realidad ofrecen muchos beneficios que superan el tiempo invertido en su creación.
¿Son una pérdida de tiempo?
No, las pruebas unitarias no son una pérdida de tiempo. Aunque inicialmente requieren una inversión de tiempo para escribirlas, a largo plazo ahorran tiempo y recursos al detectar errores temprano, reducir el tiempo de depuración y facilitar el mantenimiento y la evolución del software.
¿Duplican el tiempo de entrega?
No necesariamente. Si bien las pruebas unitarias requieren tiempo para ser escritas, este tiempo se compensa rápidamente con la reducción en el tiempo necesario para encontrar y corregir errores, así como la facilidad para realizar cambios en el código sin introducir nuevos errores. A largo plazo, las pruebas unitarias pueden acelerar el ciclo de desarrollo al reducir los retrocesos y la necesidad de corregir errores post-lanzamiento.
Ejemplo de Caso Práctico
Consideremos un proyecto sin pruebas unitarias donde un error en una función crítica se descubre tarde en el ciclo de desarrollo o incluso en producción. El costo de corregir ese error incluye no solo el tiempo de desarrollo adicional, sino también el impacto potencial en los usuarios y la reputación de la empresa. En contraste, un proyecto con pruebas unitarias probablemente hubiera detectado el error mucho antes, reduciendo significativamente estos costos.
Practica con Java y Spring Boot
Para realizar pruebas unitarias en un proyecto de Spring Boot, puedes usar JUnit, que es el marco de pruebas unitarias más popular para Java. A continuación, te proporcionaré una guía básica sobre cómo configurar y escribir pruebas unitarias en Spring Boot utilizando JUnit y Mockito.
Paso 1: Configurar el Proyecto
Asegúrate de que tu proyecto de Spring Boot tenga las dependencias necesarias para JUnit y Mockito. Aquí tienes un ejemplo de cómo se vería tu archivo pom.xml si estás usando Maven:
<dependencies>
<!-- Dependencias de Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Mockito -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Paso 2: Crear una Clase de Servicio
Supongamos que tienes una clase de servicio simple llamada UserService:
package com.example.demo.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public String getUserGreeting(String username) {
return "Hello, " + username + "!";
}
}
Paso 3: Crear la Clase de Prueba Unitaria
A continuación, se muestra cómo crear una clase de prueba para UserService utilizando JUnit y Mockito:
package com.example.demo.service;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class UserServiceTest {
@Test
public void testGetUserGreeting() {
// Arrange
UserService userService = new UserService();
// Act
String result = userService.getUserGreeting("John");
// Assert
assertEquals("Hello, John!", result);
}
}
Paso 4: Usar Mockito para Pruebas Unitarias Más Complejas
En escenarios más complejos, podrías necesitar usar Mockito para simular dependencias. Aquí hay un ejemplo donde UserService depende de UserRepository:
Clase de Servicio con Dependencia
package com.example.demo.service;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public String getUserGreeting(Long userId) {
String username = userRepository.findUsernameById(userId);
return "Hello, " + username + "!";
}
}
Interfaz del Repositorio
package com.example.demo.repository;
public interface UserRepository {
String findUsernameById(Long userId);
}
Clase de Prueba con Mockito
package com.example.demo.service;
import com.example.demo.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
public void testGetUserGreeting() {
// Arrange
Long userId = 1L;
when(userRepository.findUsernameById(userId)).thenReturn("John");
// Act
String result = userService.getUserGreeting(userId);
// Assert
assertEquals("Hello, John!", result);
}
}
Paso 5: Pruebas de Integración con Spring Boot (Opcional)
Para pruebas de integración, puedes usar @SpringBootTest para cargar el contexto completo de Spring. Aquí hay un ejemplo:
package com.example.demo.service;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest
public class UserServiceIntegrationTest {
@Autowired
private UserService userService;
@Test
public void testGetUserGreeting() {
// Act
String result = userService.getUserGreeting("John");
// Assert
assertEquals("Hello, John!", result);
}
}
Conclusión
Las pruebas unitarias son una práctica esencial y valiosa en el desarrollo de software. Aunque requieren tiempo para implementarlas, los beneficios que aportan en términos de calidad del código, facilidad de mantenimiento y confianza en el software compensan con creces el tiempo invertido. En lugar de ser una pérdida de tiempo, las pruebas unitarias son una inversión en la calidad y sostenibilidad del software.