
Einer der Gründe, warum Spring und Spring Boot so beliebt sind, ist ihre gute Testunterstützung . Sie können sowohl Komponententests mit Mockito ohne Verwendung der Spring-Funktionalität als auch Integrationstests mit der Initialisierung des Spring-Kontexts schreiben .
Integrationstests erfordern möglicherweise die Interaktion mit externen Diensten wie relationalen Datenbanken, NoSQL-Datenbanken, Kafka und anderen. Beim Testen ist es zweckmäßig, diese Dienste in Docker-Containern bereitzustellen.
Testcontainer
Aus der Dokumentation zu Testcontainers:
TestContainers ist eine Java-Bibliothek, die JUnit-Tests unterstützt, indem sie einfache, vorübergehende Instanzen für gängige Datenbanken, Webbrowser mit Selenium und alles andere bereitstellt, was in einem Docker-Container ausgeführt werden kann.
Mit Testcontainern können Sie einen Singleton Docker-Container wie folgt starten :
@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()
}
}
Da dies häufig verwendet wird, wurde von der Community ein Starter erstellt, um das Leben der Community zu vereinfachen - Testcontainers Spring Boot Starter .
Testcontainer SpringBoot Starter
Testcontainers - Der Starter ist abhängig von der feder Cloud-Starter . Wenn Ihre Anwendung keine SpringCloud-Starter verwendet, müssen Sie Spring-Cloud-Starter als Testabhängigkeit hinzufügen .
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
<scope>test</scope>
</dependency>
Fügen Sie außerdem die Bibliothek für die Datenbank hinzu. Wenn Sie beispielsweise Postgresql verwenden möchten:
<dependency>
<groupId>com.playtika.testcontainers</groupId>
<artifactId>embedded-postgresql</artifactId>
<scope>test</scope>
</dependency>
Beim Hinzufügen
embedded-postgresql
zur Umgebung stehen folgende Eigenschaften zur Verfügung:
embedded.postgresql.port
embedded.postgresql.host
embedded.postgresql.schema
embedded.postgresql.user
embedded.postgresql.password
Sie können zum Einrichten einer Datenquelle verwendet werden.
In der Regel werden Docker-Container nur für Integrationstests verwendet, nicht für Komponententests. Mithilfe von Profilen können wir sie standardmäßig deaktivieren und nur für Integrationstests aktivieren.
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}
Jetzt können Sie Integrationstests mit dem Integrationstestprofil ausführen, indem Sie
@ActiveProfiles
:
@SpringBootTest
@ActiveProfiles("integration-test")
class UserServiceIntegrationTest {
@Autowired
private UserService userService;
@Test
void shouldGetAllUsers() {
// test userService.getAllUsers()
}
}
Sie können eine bestimmte Version des Docker-Images wie folgt angeben:
src/test/resources/bootstrap-integration-test.properties
embedded.postgresql.dockerImage=postgres:10.7
embedded.postgresql.enabled=true
Der Starter von Testcontainers bietet bereits Unterstützung für die beliebtesten Container wie Postgresql, MariaDB, MongoDB, Redis, RabbitMQ, Kafka, Elasticsearch und andere.
Überraschenderweise gibt es derzeit keine direkte Unterstützung für MySQL. Es gibt zwar eine einfache Problemumgehung dafür, wie hier beschrieben
Refactoring des Anwendungscodes im Frühjahr