Skip to main content

🧪 Formato de pruebas Unitarias

📋 Información General​

CampoValorCampoValor
Proyecto: [Nombre del Proyecto]Código Proyecto: [codigo]
Sprint / Release:[Sprint 03 – Comercial]Versión del Sistema:[1.0]
Fecha de elaboración:[dd/mm/aaaa]DEV Responsable:[Nombre del DEV]
**✅ Identificador / Nombre del test: **UT-ID#US-001 `debe_crear_usuario_correctamente_cuando_cliente_es_premium`
Objetivo: Validar que el sistema cree correctamente un usuario cuando recibe datos válidos.
Tipo de Prueba:[Unitaria / Mock de repositorio / Sin acceso real a BD]

✅ Identificador / Nombre del test:​

UT-ID#US-001 `debe_crear_usuario_correctamente_cuando_cliente_es_premium`

Objetivo: Validar que el sistema cree correctamente un usuario cuando recibe datos válidos.

Tipo de Prueba: [Unitaria / Mock de repositorio / Sin acceso real a BD]

🎯 Vista rápida de la prueba

⚙️ Método/Clase bajo prueba​

UserService.createUser()

public class UserService {

private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;

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

public User register(String name, String email, String password) {

if (userRepository.existsByEmail(email)) {
throw new IllegalArgumentException("Email already registered");
}

String encodedPassword = passwordEncoder.encode(password);
User user = new User(name, email, encodedPassword);

return userRepository.save(user);
}
}

🔐 Precondiciones​

  • Base de datos accesible
  • Email no registrado previamente

📥 Datos de entrada​

{
"name": "Juan",
"email": "juan@test.com",
"password": "123456"
}

🎯 Resultado esperado​

  • Usuario persistido
  • ID generado
  • No se lanza excepción
✅ Resultado esperado

🧪 Implementación de la prueba unitaria​

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

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

@ExtendWith(MockitoExtension.class)
class UserServiceTest {

@Mock
private UserRepository userRepository;

@Mock
private PasswordEncoder passwordEncoder;

@InjectMocks
private UserService userService;

private final String NAME = "Juan";
private final String EMAIL = "juan@test.com";
private final String PASSWORD = "123456";

@Test
@DisplayName("register_conDatosValidos_guardaUsuarioCorrectamente")
void register_conDatosValidos_guardaUsuarioCorrectamente() {
// Arrange
when(userRepository.existsByEmail(EMAIL)).thenReturn(false);
when(passwordEncoder.encode(PASSWORD)).thenReturn("encodedPassword");

User savedUser = new User(NAME, EMAIL, "encodedPassword");
when(userRepository.save(any(User.class))).thenReturn(savedUser);

// Act
User result = userService.register(NAME, EMAIL, PASSWORD);

// Assert
assertNotNull(result);
assertEquals(EMAIL, result.getEmail());
assertEquals("encodedPassword", result.getPassword());

verify(userRepository).existsByEmail(EMAIL);
verify(passwordEncoder).encode(PASSWORD);
verify(userRepository).save(any(User.class));
}

@Test
@DisplayName("register_conEmailDuplicado_lanzaExcepcion")
void register_conEmailDuplicado_lanzaExcepcion() {
// Arrange
when(userRepository.existsByEmail(EMAIL)).thenReturn(true);

// Act & Assert
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> userService.register(NAME, EMAIL, PASSWORD)
);

assertEquals("Email already registered", exception.getMessage());

verify(userRepository, never()).save(any());
verify(passwordEncoder, never()).encode(any());
}
}

🧠 Flujo Arrange → Act → Assert​

🔀 Escenarios cubiertos por el ejemplo​


📊 Cobertura asociada​

  • Línea:
  • Rama:
  • Caso límite cubierto
📈 Cobertura

📦 Dependencias​

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.8</version>
<scope>test</scope>
</dependency>

✅ NOTA: Buenas prácticas que se deben de incluir en las pruebas

Unitarias

Me enfoco en:

  • ✅ Casos felices
  • ✅ Casos límite (boundary values)
  • ✅ Casos negativos
  • ✅ Manejo de excepciones
  • ✅ Comportamiento ante null o valores vacíos
  • ✅ Verificación de efectos secundarios
  • ✅ Independencia del test
  • ✅ Tests rápidos y determinísticos
  • ✅Métricas de cobertura mínima (ej: 80%+)
  • ✅Reportes automatizados (Sonar, CI)
  • ✅Convenciones obligatorias de naming
  • ✅Tests parametrizados para reducir duplicación :::

🎮 Mapa visual de buenas prácticas​


🚀 Ciclo visual completo