
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-postgresql
ao 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