Spring和Spring Boot如此受欢迎的原因之一是其良好的测试支持。您可以使用Mockito编写单元测试而不使用Spring功能,也可以使用Spring上下文的初始化编写集成测试。
集成测试可能需要与外部服务进行交互,例如关系数据库,NoSQL数据库,Kafka等。测试时,将这些服务部署在Docker容器中非常方便。
测试容器
从Testcontainers文档中:
TestContainers是一个Java库,通过为流行的数据库,带有Selenium的Web浏览器以及可以在Docker容器中运行的任何其他程序提供轻量级的临时实例,来支持JUnit测试。
使用Testcontainers,您可以按以下方式启动Singleton Docker容器:
@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()
}
}
由于经常使用它,因此社区创建了一个启动程序,以简化社区的工作-Testcontainers Spring Boot Starter。
测试容器SpringBoot Starter
Testcontainers-启动器取决于spring-cloud-starter。如果您的应用程序不使用SpringCloud启动器,那么您需要添加spring-cloud-starter作为测试依赖项。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
<scope>test</scope>
</dependency>
并添加数据库的库。例如,如果要使用Postgresql:
<dependency>
<groupId>com.playtika.testcontainers</groupId>
<artifactId>embedded-postgresql</artifactId>
<scope>test</scope>
</dependency>
当添加
embedded-postgresql
到环境中时,以下属性将可用:
embedded.postgresql.port
embedded.postgresql.host
embedded.postgresql.schema
embedded.postgresql.user
embedded.postgresql.password
它们可用于设置数据源。
通常,Docker容器仅用于集成测试,而不用于单元测试。借助配置文件,我们可以默认禁用它们,并且仅在集成测试中启用它们。
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}
现在你可以运行与集成测试,集成测试配置文件使用
@ActiveProfiles
:
@SpringBootTest
@ActiveProfiles("integration-test")
class UserServiceIntegrationTest {
@Autowired
private UserService userService;
@Test
void shouldGetAllUsers() {
// test userService.getAllUsers()
}
}
您可以指定特定版本的Docker映像,如下所示:
src/test/resources/bootstrap-integration-test.properties
embedded.postgresql.dockerImage=postgres:10.7
embedded.postgresql.enabled=true
测试容器入门程序已经提供了对最受欢迎的容器的支持,例如Postgresql,MariaDB,MongoDB,Redis,RabbitMQ,Kafka,Elasticsearch等。
令人惊讶的是,目前尚无对MySQL的直接支持。虽然这一个简单的解决方法描述在这里
在Spring中重构应用程序代码