I’m developing a microservice about trainers and their messages in Spring using Rest. I have the controllers and services created (with their corresponding http request implementations created), and so far everything was working fine, apart from the tests.
I have seen that it is possible to include security in my microservice through JWT, but from here is when the problems have arrived. When I launch the tests, I am now getting the following error:
[ERROR] MicroservicioEntrenadoresApplicationTests$BaseDatosVacia.modificarEntrenadorInexistente » UnsatisfiedDependency Error creating bean with name 'es.uma.informatica.practica3.MicroservicioEntrenadoresApplicationTests': Unsatisfied dependency expressed through field 'restTemplateX': No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@DisplayName("En el servicio de entrenadores y sus mensajes,")
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
class MicroservicioEntrenadoresApplicationTests {
@Autowired
private RestTemplate restTemplate;
// Para poder extraer el puerto de nuestra maquina donde Spring ha lanzado las pruebas...
@Value(value="${local.server.port}")
private int port;
@Autowired
private EntrenadorRepository entrenadorRepo;
@Autowired
private MensajeRepository mensajeRepo;
@Autowired
private JwtUtil jwtUtil;
// Extraido de la solucion del profesor del CV sobre el taller de pruebas de jUnit
private URI uri(String scheme, String host, int port, String ...paths) {
UriBuilderFactory ubf = new DefaultUriBuilderFactory();
UriBuilder ub = ubf.builder()
.scheme(scheme)
.host(host).port(port);
for (String path: paths) {
ub = ub.path(path);
}
return ub.build();
}
// Para aquellas consultas que requieran de un @RequestParam
private URI uriWithParam(String scheme, String host, int port, String paths, String rP) {
UriBuilderFactory ubf = new DefaultUriBuilderFactory();
UriBuilder ub = ubf.builder()
.scheme(scheme)
.host(host).port(port).path(paths);
String[] partes = rP.split("=");
ub.queryParam(partes[0], partes[1]);
System.out.println("La peticion post es: " + ub.toUriString());
return ub.build();
}
// Extraido de la solucion del profesor del CV sobre el taller de pruebas de jUnit
private RequestEntity<Void> get(String scheme, String host, int port, String path) {
URI uri = uri(scheme, host,port, path);
UserDetails userDetails = new User("username","password",
List.of("ROLE_USER").stream()
.map(SimpleGrantedAuthority::new)
.toList());
String token = jwtUtil.generateToken(userDetails);
var peticion = RequestEntity.get(uri)
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + token)
.build();
return peticion;
}
private RequestEntity<Void> get(String scheme, String host, int port, String path, String requestParam) {
URI uri = uriWithParam(scheme, host,port, path, requestParam);
UserDetails userDetails = new User("username","password",
List.of("ROLE_USER").stream()
.map(SimpleGrantedAuthority::new)
.toList());
String token = jwtUtil.generateToken(userDetails);
var peticion = RequestEntity.get(uri)
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + token)
.build();
return peticion;
}
// Extraido de la solucion del profesor del CV sobre el taller de pruebas de jUnit
private RequestEntity<Void> delete(String scheme, String host, int port, String path) {
URI uri = uri(scheme, host,port, path);
UserDetails userDetails = new User("username","password",
List.of("ROLE_USER").stream()
.map(SimpleGrantedAuthority::new)
.toList());
String token = jwtUtil.generateToken(userDetails);
var peticion = RequestEntity.delete(uri)
.header("Authorization", "Bearer " + token)
.build();
return peticion;
}
private <T> RequestEntity<T> post(String scheme, String host, int port, String path, String requestParam, T object) {
URI uri = uriWithParam(scheme, host,port, path, requestParam);
UserDetails userDetails = new User("username","password",
List.of("ROLE_USER").stream()
.map(SimpleGrantedAuthority::new)
.toList());
String token = jwtUtil.generateToken(userDetails);
var peticion = RequestEntity.post(uri)
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + token)
.body(object);
return peticion;
}
// Extraido de la solucion del profesor del CV sobre el taller de pruebas de jUnit
private <T> RequestEntity<T> put(String scheme, String host, int port, String path, T object) {
URI uri = uri(scheme, host,port, path);
UserDetails userDetails = new User("username","password",
List.of("ROLE_USER").stream()
.map(SimpleGrantedAuthority::new)
.toList());
String token = jwtUtil.generateToken(userDetails);
var peticion = RequestEntity.put(uri)
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + token)
.body(object);
return peticion;
}
@Nested
@DisplayName("cuando la base de datos está vacía")
public class BaseDatosVacia {
@Test
@DisplayName("error al obtener un entrenador concreto")
public void errorAlObtenerEntrenadorConcreto() {
var peticion = get("http", "localhost",port, "/entrenador/1");
var respuesta = restTemplate.exchange(peticion,
new ParameterizedTypeReference<EntrenadorDTO>() {});
assertThat(respuesta.getStatusCode().value()).isEqualTo(404);
}
@Test
@DisplayName("devuelve error al modificar un entrenador que no existe")
public void modificarEntrenadorInexistente () {
EntrenadorDTO trainer = new EntrenadorDTO();
trainer.setIdUsuario(123L);
var peticion = put("http", "localhost",port, "/entrenador/1", trainer);
var respuesta = restTemplate.exchange(peticion, Void.class);
assertThat(respuesta.getStatusCode().value()).isEqualTo(404);
}
@Test
@DisplayName("devuelve error al eliminar un entrenador que no existe")
public void eliminarEntrenadorInexistente () {
var peticion = delete("http", "localhost",port, "/entrenador/1");
var respuesta = restTemplate.exchange(peticion, Void.class);
assertThat(respuesta.getStatusCode().value()).isEqualTo(404);
}
@Test
@DisplayName("inserta correctamente un entrenador")
public void insertaEntrenador() {
EntrenadorDTO trainer = new EntrenadorDTO();
trainer.setIdUsuario(123L);
trainer.setEspecialidad("Especialidad de prueba");
var peticion = post("http", "localhost",port, "/entrenador", "centro=1" ,trainer);
var respuesta = restTemplate.exchange(peticion,Void.class);
assertThat(respuesta.getStatusCode().value()).isEqualTo(201);
assertThat(respuesta.getHeaders().get("Location").get(0))
.startsWith("http://localhost:"+port+"/entrenador");
List<Entrenador> allTrainers = entrenadorRepo.findAll();
assertThat(allTrainers).hasSize(1);
assertThat(respuesta.getHeaders().get("Location").get(0))
.endsWith("/"+allTrainers.get(0).getId());
}
}