Teste de integração no SpringBoot com o iniciador TestContainers

A tradução do artigo foi preparada em antecipação ao início do curso "Desenvolvedor no Spring Framework" .








Uma das razões pelas quais Spring e Spring Boot são tão populares é seu bom suporte a testes . Você pode escrever testes de unidade com Mockito sem usar a funcionalidade Spring e testes de integração com a inicialização do contexto Spring.



Os testes de integração podem exigir interação com serviços externos, como bancos de dados relacionais, bancos de dados NoSQL, Kafka e outros. Ao testar, é conveniente implantar esses serviços em contêineres do Docker.



Testcontainers



Da documentação do Testcontainers:



TestContainers é uma biblioteca Java que oferece suporte a testes JUnit, fornecendo instâncias leves e temporárias para bancos de dados populares, navegadores da web com Selenium e qualquer outra coisa que possa ser executada em um contêiner Docker.




Usando Testcontainers, você pode iniciar um contêiner Singleton Docker da seguinte maneira:



@SpringBootTest
@ContextConfiguration(initializers = {UserServiceIntegrationTest.Initializer.class})
class UserServiceIntegrationTest {
    private static PostgreSQLContainer sqlContainer;
    
    static {
        sqlContainer = new PostgreSQLContainer("postgres:10.7")
                .withDatabaseName("integration-tests-db")
                .withUsername("sa")
                .withPassword("sa");
        sqlContainer.start();
    }

    static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
            TestPropertyValues.of(
              "spring.datasource.url=" + sqlContainer.getJdbcUrl(),
              "spring.datasource.username=" + sqlContainer.getUsername(),
              "spring.datasource.password=" + sqlContainer.getPassword()
            ).applyTo(configurableApplicationContext.getEnvironment());
        }
    }

    @Autowired
    private UserService userService;
    
    @Test
    void shouldGetAllUsers() {
        // test userService.getAllUsers()
    }   

}


Como isso é usado com frequência, um starter foi criado pela comunidade para simplificar a vida da comunidade - Testcontainers Spring Boot Starter .



Testcontainers SpringBoot Starter



Testcontainers - O starter depende do starter da nuvem-mola . Se seu aplicativo não usa starters SpringCloud, você precisa adicionar spring-cloud-starter como uma dependência de teste.



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


E também adicione a biblioteca para o banco de dados. Por exemplo, se você deseja usar Postgresql:



<dependency>
    <groupId>com.playtika.testcontainers</groupId>
    <artifactId>embedded-postgresql</artifactId>
    <scope>test</scope>
</dependency>


Quando adicionadas embedded-postgresqlao ambiente, as seguintes propriedades estarão disponíveis:



embedded.postgresql.port
embedded.postgresql.host
embedded.postgresql.schema
embedded.postgresql.user
embedded.postgresql.password


Eles podem ser usados ​​para configurar uma fonte de dados.



Normalmente, os contêineres Docker são usados ​​apenas para testes de integração, não testes de unidade. Com a ajuda de perfis, podemos desabilitá-los por padrão e habilitá-los apenas para testes de integração.



src/test/resources/bootstrap.properties



embedded.postgresql.enabled=false


src/test/resources/bootstrap-integration-test.properties



embedded.postgresql.enabled=true
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://${embedded.postgresql.host}:${embedded.postgresql.port}/${embedded.postgresql.schema}
spring.datasource.username=${embedded.postgresql.user}
spring.datasource.password=${embedded.postgresql.password}


Agora você pode executar testes de integração com o perfil de teste de integração usando @ActiveProfiles:



@SpringBootTest
@ActiveProfiles("integration-test")
class UserServiceIntegrationTest {
    
    @Autowired
    private UserService userService;
    
    @Test
    void shouldGetAllUsers() {
        // test userService.getAllUsers()
    }   

}


Você pode especificar uma versão específica da imagem docker da seguinte maneira:



src/test/resources/bootstrap-integration-test.properties



embedded.postgresql.dockerImage=postgres:10.7
embedded.postgresql.enabled=true




O iniciador testcontainers já fornece suporte para os containers mais populares, como Postgresql, MariaDB, MongoDB, Redis, RabbitMQ, Kafka, Elasticsearch e outros.

Surpreendentemente, atualmente não há suporte direto para MySQL. Embora haja uma solução simples para isso, conforme descrito aqui






Refatorando o código do aplicativo no Spring







All Articles