Si habéis estado trabajando con las validaciones hechas con anterioridad, y mas concretamente en la validación de cine, este articulo no aporta gran cosa, pero vale para daros una visión optimizada
Preparando la aplicación
Igual que hicimos en el articulo anterior, en donde creábamos un filtro de DNI, lo primero que debemos recordar es añadir la dependencia a nuestra aplicacion, que si estamos trabajando con SpringBoot y maven, será añadirle al pom.xml
<!-- Para las validaciones -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- fin validaciones -->
y después ya podemos iniciar nuestro trabajo
Creación de la anotación @CheckEntradaValidation
Esta vez, y teniendo ya hecha la validación de cine, me limite, primero, a copiar la interface,
@Target( { FIELD, PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = CheckEntradaValidator.class)
public @interface CheckEntradaValidation {
public String message() default "Se ha indicado una entrada que no existe";
public Class<?>[] groups() default {};
public Class<? extends Payload>[] payload() default {};
}
y modificar la clase de validación para que fuera CheckEntradaValidator, y el letrero de error, para que hablara de entrada, en vez de cine
A continuación, y siguiendo esta forma «tan costosa» de trabajar, duplique la clase CheckCineValidator y la corregí, para trabajar sobre entrada, quedando así:
public class CheckEntradaValidator implements ConstraintValidator<CheckEntradaValidation, Long>{
private final EntradaService entradaService;
CheckEntradaValidator(EntradaService entradaService){
this.entradaService=entradaService;
}
@Override
public boolean isValid(Long entrada, ConstraintValidatorContext context) {
if (entrada == null) return true;
return entradaService.existsById(entrada);
}
}
Como podéis ver, poco mas de 5 minutos, tecleando lento, pero he intentado dejarlo todo con sentido….
Como veis, el filtro es muy sencillo, me basta con recibir el repositorio de Entrada, y utilizar un método previsto en él, que es existById que me devuelve true o false, por lo que lo retorno en isValid, y con eso queda hecha la comprobación.
Las pruebas
El siguiente paso, es preparar un modulo para poder realizar las pruebas con Junit5. De momento, tenemos que verificar que la clase construida existe, y para ello y, ya que estamos en un entorno Spring, lo tendremos en cuenta, aunque deberemos utilizar mockito para interferir el acceso a la base de datos que intentará hacer EntradaServicio para comprobar la existencia
De momento, deberemos ir al paquete .util.constraint.validator del área de test, para crear la clase
@ExtendWith(MockitoExtension.class)
public class CheckEntradaValidatorSpringTest {
@Mock
private EntradaService entradaService;
@MockBean
private ConstraintValidatorContext context;
Necesitamos el contexto, y, como no trabajamos con toda la generación de Spring, nos creamos un EntradaService con @Mock, y no @MockBean, para el que, aquí, le faltaría información
Nos creamos una pequeña función para realizar los test
boolean probar(Long entradaId) {
return new CheckEntradaValidator(entradaService).isValid(entradaId, context);
}
Lo único que hace, es instanciar la clase, y retornar el resultado de isValid, que es lo que deseamos probar. Ahora, ya podemos realizar los test y ver los resultados, por ejemplo, así:
@Test
public void testIsValidWithValidEntrada() {
Long entradaId = 1L;
when(entradaService.existsById(entradaId)).thenReturn(true);
boolean result = probar(entradaId);
assertTrue(result);
verify(entradaService).existsById(entradaId);
}
@Test
public void testIsValidWithNullEntrada() {
Long entradaId = null;
boolean result = probar(entradaId);
assertTrue(result);
verify(entradaService, never()).existsById(anyLong());
}
@Test
public void testNotValidWidthInvalidData() {
Long entradaId = 1L;
when(entradaService.existsById(entradaId)).thenReturn(false);
boolean result = probar(entradaId);
assertFalse(result);
verify(entradaService).existsById(entradaId);
}
Para las pruebas de Valid e Invalid, creo el comportamiento de entradaService, para que responda con true o false, según interese. Escribo el Assert que necesito, y, verifico que se haya usado el mock que he creado
Para la prueba null, no debo crear ningún mock, porque si miramos el código, veremos que si recibimos null, no realizamos el acceso a la base de datos, con lo cual, me limito a verificar que no se ha utilizado la función.
Conclusión
Todo este desarrollo lo tenéis explicado con mas detalle en youTube (a partir de 1/06/24) , y, aunque es conveniente que intentéis escribirlo TODO vosotros, si queréis renunciar a ello, lo tenéis también en GitHub
Este desarrollo esta hecho para disponer de un fuente para explicar otros temas, tal y como se indica en Visión de conjunto con Spring
Relacionado
Descubre más desde Recursos para formacion
Suscríbete y recibe las últimas entradas en tu correo electrónico.