Les proves d'integració són una part essencial del desenvolupament de programari, ja que asseguren que diferents components del sistema funcionin correctament quan es combinen. En aquest tema, aprendrem com realitzar proves d'integració en aplicacions Spring Boot.

Objectius del tema

  • Entendre què són les proves d'integració i la seva importància.
  • Configurar l'entorn per a les proves d'integració en Spring Boot.
  • Escriure i executar proves d'integració utilitzant Spring Boot Test.
  • Utilitzar bases de dades en memòria per a proves d'integració.

Què són les proves d'integració?

Les proves d'integració verifiquen que diferents mòduls o serveis d'una aplicació funcionin correctament quan es combinen. A diferència de les proves unitàries, que aïllen i proven components individuals, les proves d'integració asseguren que les interaccions entre components siguin correctes.

Importància de les proves d'integració

  • Verificació de la interacció: Asseguren que els components funcionin correctament quan es combinen.
  • Detecció de problemes d'integració: Identifiquen problemes que poden no ser evidents en proves unitàries.
  • Confiança en el sistema: Proporcionen confiança que el sistema complet funciona com s'espera.

Configuració de l'entorn per a proves d'integració

Spring Boot proporciona un suport excel·lent per a les proves d'integració a través del mòdul spring-boot-starter-test, que inclou biblioteques com JUnit, Spring Test, AssertJ, Hamcrest i Mockito.

Dependències necessàries

Assegura't de tenir les següents dependències en el teu fitxer pom.xml (per a Maven) o build.gradle (per a Gradle):

Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

Gradle:

testImplementation 'org.springframework.boot:spring-boot-starter-test'

Escriure proves d'integració

Exemple pràctic

Suposem que tenim un servei que gestiona usuaris i volem provar la seva integració amb el controlador REST i el repositori JPA.

Controlador d'Usuari:

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return ResponseEntity.ok(user);
    }
}

Servei d'Usuari:

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public User getUserById(Long id) {
        return userRepository.findById(id).orElseThrow(() -> new UserNotFoundException("User not found"));
    }
}

Repositori d'Usuari:

public interface UserRepository extends JpaRepository<User, Long> {
}

Prova d'integració

Prova d'integració del controlador d'usuari:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserControllerIntegrationTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private UserRepository userRepository;

    @Before
    public void setUp() {
        User user = new User();
        user.setName("John Doe");
        userRepository.save(user);
    }

    @Test
    public void testGetUserById() {
        ResponseEntity<User> response = restTemplate.getForEntity("/users/1", User.class);
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("John Doe", response.getBody().getName());
    }
}

Explicació del codi

  • Configuració de la prova: Utilitzem @SpringBootTest per carregar el context complet de Spring Boot. webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT indica que es crearà un servidor web en un port aleatori per a les proves.
  • TestRestTemplate: S'utilitza per fer sol·licituds HTTP al servidor de proves.
  • @Before: Configura les dades necessàries abans de cada prova.
  • @Test: Defineix una prova que verifica que el controlador retorna l'usuari correcte.

Utilitzant bases de dades en memòria

Per a les proves d'integració, és recomanable utilitzar bases de dades en memòria com H2 per evitar modificar dades reals.

Configuració de H2

application.properties:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

Exercici pràctic

Exercici

  1. Crea un nou projecte Spring Boot.
  2. Implementa un controlador, servei i repositori per gestionar entitats de "Producte".
  3. Escriu una prova d'integració per verificar que el controlador retorna correctament un producte per ID.

Solució

Controlador de Producte:

@RestController
@RequestMapping("/products")
public class ProductController {

    @Autowired
    private ProductService productService;

    @GetMapping("/{id}")
    public ResponseEntity<Product> getProductById(@PathVariable Long id) {
        Product product = productService.getProductById(id);
        return ResponseEntity.ok(product);
    }
}

Servei de Producte:

@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    public Product getProductById(Long id) {
        return productRepository.findById(id).orElseThrow(() -> new ProductNotFoundException("Product not found"));
    }
}

Repositori de Producte:

public interface ProductRepository extends JpaRepository<Product, Long> {
}

Prova d'integració del controlador de producte:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ProductControllerIntegrationTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private ProductRepository productRepository;

    @Before
    public void setUp() {
        Product product = new Product();
        product.setName("Laptop");
        productRepository.save(product);
    }

    @Test
    public void testGetProductById() {
        ResponseEntity<Product> response = restTemplate.getForEntity("/products/1", Product.class);
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("Laptop", response.getBody().getName());
    }
}

Resum

En aquest tema, hem après què són les proves d'integració i la seva importància en el desenvolupament de programari. Hem configurat l'entorn per a les proves d'integració en Spring Boot, hem escrit proves d'integració utilitzant TestRestTemplate i hem utilitzat bases de dades en memòria per a les proves. A més, hem realitzat un exercici pràctic per reforçar els conceptes apresos. Ara estàs preparat per escriure proves d'integració efectives en les teves aplicacions Spring Boot.

Curs de Spring Boot

Mòdul 1: Introducció a Spring Boot

Mòdul 2: Conceptes bàsics de Spring Boot

Mòdul 3: Construint serveis web RESTful

Mòdul 4: Accés a dades amb Spring Boot

Mòdul 5: Seguretat a Spring Boot

Mòdul 6: Proves a Spring Boot

Mòdul 7: Funcions avançades de Spring Boot

Mòdul 8: Desplegant aplicacions Spring Boot

Mòdul 9: Rendiment i monitorització

Mòdul 10: Millors pràctiques i consells

© Copyright 2024. Tots els drets reservats