| Tabla de contenidos |
|---|
...
Vamos a ver cómo realizar tests en nuestros proyectos Spring Boot, con ejemplos de algunas acciones básicas.
| Advertencia |
|---|
Se está reestructurando esta documentación |
Para hacer tests sobre los métodos de nuestros controladores REST, utilizaremos Junit y Mockito. Veamos en primer lugar un ejemplo completo, para pasar a explicarlo a continuación:
| Bloque de código | ||
|---|---|---|
| ||
package es.um.atica.portalfundewebbackend;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import es.um.atica.portalfundewebbackend.entities.portalfundeweb.Componente;
import es.um.atica.portalfundewebbackend.repositories.portalfundeweb.ComponenteRepository;
import es.um.atica.portalfundewebbackend.repositories.portalfundeweb.ComunicacionComponenteRepository;
import es.um.atica.portalfundewebbackend.repositories.portalfundeweb.ComunicacionRepository;
import es.um.atica.portalfundewebbackend.rest.RestComunicaciones;
public class RestComunicacionesTest {
@Mock
private ComunicacionRepository comunicacionRespository;
@Mock
private ComponenteRepository componenteRepository;
@Mock
private ComunicacionComponenteRepository comunicacionComponenteRepository;
private RestComunicaciones restComunicaciones;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
restComunicaciones = new RestComunicaciones(comunicacionRespository, componenteRepository, comunicacionComponenteRepository);
Componente comp = new Componente(1L, "Componente de prueba", "Etiqueta", "Hola buenas tardes");
Mockito.when(componenteRepository.findById(comp.getId()))
.thenReturn(comp);
}
@Test
public void getComponenteById() {
Long id = 1L;
Componente found = restComunicaciones.getComponente(id);
assertThat(found.getId()).isEqualTo(id);
}
} |
Como vemos, hacemos mocks de los repositorios, es decir, simulamos los datos de base de datos, pues en estos tests no se accede a la base de datos real. En primer lugar, tenemos el método setup, en el que inicializamos los mocks, nuestros servicios, e indicamos el comportamiento deseado de los métodos que vayamos a utilizar. Con la etiqueta @Before indicamos que esto se ejecutará siempre antes de hacer un test:
| Bloque de código | ||
|---|---|---|
| ||
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
restComunicaciones = new RestComunicaciones(comunicacionRespository, componenteRepository, comunicacionComponenteRepository);
Componente comp = new Componente(1L, "Componente de prueba", "Etiqueta", "Hola buenas tardes");
Mockito.when(componenteRepository.findById(comp.getId()))
.thenReturn(comp);
} |
En este caso, indicamos que se devuelva un componente concreto cuando se llama al método findById del repositorio.
Por último, el método que hace el test es getComponenteById, donde ha de cumplirse las condiciones que pongamos con assertThat:
...
| language | java |
|---|
...
Clases de tests
Las clases en las que situemos nuestros tests tendrás que ir precedidas de la anotación @SpringBootTest:
...
| Bloque de código | ||
|---|---|---|
| ||
@Test
void getExpedienteTest() {
} |
Before: ejecutar código antes de los tests
Disponemos de las anotaciones @BeforeEach y @BeforeAll para indicar código que queremos que se ejecute antes de cada test, o antes de todos los tests, respectivamente. Por ejemplo, para indicar que queremos hacer un mock (los mocks se explican más adelante) de la propiedad que contiene el secret antes de los tests, podemos hacerlo así:
| Bloque de código | ||
|---|---|---|
| ||
@BeforeEach
void mocksecret() {
ReflectionTestUtils.setField( jwtTokenUtil, "secret", "secreto" );
} |
Comprobar valores
En nuestros tests, disponemos de diferentes formas de hacer aserciones. La primera de ellas, para comprobar valores, sería utilizando assertThat, que proporciona diferentes métodos para comprobar los valores (isNull, isEmpty, isEqualTo, etc.):
...
| Bloque de código |
|---|
import static org.junit.jupiter.api.Assertions.assertThrows; assertThrows( TokenExpiredException.class, () -> jwtTokenUtil.getClaim( "Bearer " + tokenCaducado ) ); assertThrows( UnauthorizedException.class, () -> jwtTokenUtil.getClaim( "asdf" ) ); |
Mocks
Podemos mockear una propiedad de un objeto como hemos visto en un ejemplo anterior, utilizando ReflectionTestUtils.setField, indicando el objeto, el nombre de la propiedad, y el valor a asignarle:
...
| Bloque de código |
|---|
import static org.mockito.ArgumentMatchers.any; ... Map<String, Object> infoUser = new HashMap<>(); infoUser.put( "roleName", "G_OTROS" ); final Instant now = Instant.now(); // Creamos token con el usuario "guillermo.castillo@ticarum.es", codificado con el secret "secreto" String token = Jwts.builder().setClaims( infoUser ).setSubject( "guillermo.castillo@ticarum.es" ) .setIssuedAt( Date.from( now ) ).setExpiration( Date.from( now.plus( Duration.ofDays( 123 ) ) ) ) .signWith( SignatureAlgorithm.HS256, TextCodec.BASE64.encode( "secreto" ) ).compact(); final Claims claims = Jwts.parser().setSigningKey( TextCodec.BASE64.encode( "secreto" ) ).parseClaimsJws( token ).getBody(); // Mock getClaims Mockito.when( jwtTokenUtil.getClaim( "asdf" ) ).thenReturn(claims); // Mock getClaims con cualquier argumento String Mockito.when( jwtTokenUtil.getClaim( any(String.class) ).thenReturn(claims); |
Simular peticiones a servicio REST
Para simular peticiones http a nuestros servicios REST podemos hacer uso de mockMvc, de este modo:
...
Este es un ejemplo muy simple, pero podemos ver que se realiza una llamada get (habiendo añadido el import static), y se espera que la respuesta sea un 200 OK.
Documentación
- Testing: https://www.baeldung.com/spring-boot-testing
- Spring Boot Starter Web (mockMvc): https://spring.io/guides/gs/testing-web/
- Mocks Mockito: https://www.baeldung.com/injecting-mocks-in-spring
- MockMvcRequestBuilders: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/web/servlet/request/MockMvcRequestBuilders.html#get-java.net.URI-
- MockMvcResultMatchers: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/web/servlet/result/MockMvcResultMatchers.html