Vamos a crear el controlador de películas, pero para eso nos podría interesar disponer de una anotación que nos compruebe si existe ya el id de película que vamos a usar, para usarla en el controlador y allí donde nos interese, y para eso, SpringBoot nos permite utilizar anotaciones creadas por nosotros; pues bien: vamos a crear la anotación @CheckPeliculaValidation, y a continuación, prepararemos el test de Junit5 utilizando mockito.
La estructura
Como vimos en otros artículos, para escribir la anotación, deberemos definir una interface, que establecerá el nombre de la anotación, y la configuración de la misma, y, a continuación, una clase que resolverá la funcionalidad por medio del método isValid.
La interface
Esta es la interface:
@Target( { FIELD, PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = CheckPeliculaValidator.class)
public @interface CheckPeliculaValidation {
public String message() default "Se ha indicado una pelicula que no existe";
public Class<?>[] groups() default {};
public Class<? extends Payload>[] payload() default {};
}
La parte que más conviene recordar es que por medio de @Constraint le indicamos la clase que hará la validación real, y en default, dejamos el mensaje por defecto que utilizará
La Clase
Para la clase, solo debemos implementar la interface ConstraintValidator, y resolver en el método isValid el booleano que indica si es correcto o erróneo.
Algo como esto
public class CheckPeliculaValidator implements ConstraintValidator<CheckPeliculaValidation, Long>{
private final PeliculaService peliculaService;
CheckPeliculaValidator(PeliculaService peliculaService){
this.peliculaService=peliculaService;
}
@Override
public boolean isValid(Long pelicula, ConstraintValidatorContext context) {
if (pelicula == null) return true;
return peliculaService.existe(pelicula);
}
}
Como veis, me limito a recibir PeliculaService por medio del constructor, y, luego utilizamos el método existe para hacer la comprobación…y listo!
El test de Junit5
Para el test, debemos utilizar mockito para no depender de la base de datos, por lo demás, sólo debemos probar un método, por lo que podríamos escribir algo como esto:
@ExtendWith(MockitoExtension.class)
public class CheckPeliculaValidatorSpringTest {
@Mock
private PeliculaService peliculaService;
@MockBean
private ConstraintValidatorContext context;
@Test
public void testIsValidWithValidPelicula() {
Long peliculaId = 1L;
when(peliculaService.existe(peliculaId)).thenReturn(true);
boolean result = probar(peliculaId);
assertTrue(result);
verify(peliculaService).existe(peliculaId);
}
@Test
public void testIsValidWithNullPelicula() {
Long peliculaId = null;
boolean result = probar(peliculaId);
assertTrue(result);
verify(peliculaService, never()).existe(anyLong());
}
@Test
public void testNotValidWidthInvalidData() {
Long peliculaId = 1L;
when(peliculaService.existe(peliculaId)).thenReturn(false);
boolean result = probar(peliculaId);
assertFalse(result);
verify(peliculaService).existe(peliculaId);
}
boolean probar(Long peliculaId) {
return new CheckPeliculaValidator(peliculaService).isValid(peliculaId, context);
}
}
Con la anotación @ExtendWith, ya conseguimos que se inicialice el entorno Spring, además de añadir Mockito
Luego, deberemos añadir un PeliculaService totalmente falso, generado por mockito, y empezar a realizar las prueba, si os fijais, hacemos las tres de rigor:
- testIsValidWithValidPelicula Comportamiento cuando el id existe
- Indicamos a mockito que devuelva true cuando alguien pregunte por la pelicula 1
- Hacemos la llamada por medio de una función sencilla (probar)
- Comprobamos que devuelve true, y que se ha ejecutado la función falseada.
- testIsValidWithNullPelicula Comportamiento si la película llega null
- No necesitamos mockito, porque sabemos que en ese caso, no se debe ni acceder ala BBDD,
- Hacemos la llamada por medio de una función sencilla (probar)
- Comprobamos que devuelve true, y que NO se ha ejecutado la función falseada.
- testNotValidWidthInvalidData Comportamiento cuando el id facilitado no existe en la tabla
- Indicamos a mockito que devuelva false cuando alguien pregunte por la pelicula 1
- Hacemos la llamada por medio de una función sencilla (probar)
- Comprobamos que devuelve false, y que se ha ejecutado la función falseada.
y si obtenemos la banda verde, todo va bien, y posiblemente la validación funcionará correctamente
Conclusión
Todo este desarrollo lo tendreis explicado con mas detalle en youTube, en un par de dias, lo vereis tambien al pie del articulo, y, aunque es conveniente que intentéis escribirlo TODO vosotros, si queréis renunciar a ello, lo teneis tambien en GitHub
Este desarrollo está hecho para disponer de un fuente para explicar otros temas, tal y como se indica en Visión de conjunto con Spring