Writing Integration Tests for a Spring Repository With Kotlin and JUnit 5: Configuration
After we have finished this lesson, we:
- Can start and stop a Docker container which runs a PostgreSQL database.
- Understand how we can eliminate duplicate configuration code when we configure our integration tests.
This lessons assumes that:
- You are familiar with DbUnit
- You can configure your integration tests when you are using JUnit 4
- You are familiar with JUnit 5
- You are familiar with TestContainers
- You can integrate TestContainers with JUnit 5
- You can write integration tests with JUnit 5 and TestContainers
- You can run Kotlin tests with Maven or Gradle .
Get the source code from Github
Configuring Our Database Connection
Before we can configure our integration tests, we have to ensure that TestContainers starts a PostgreSQL database before our integration tests are run. We can do this by following these steps:
First, we have to ensure that our classpath contains both TestContainers and the PostgreSQL JDBC driver.
Second, we have to configure our database connection by making the following changes to our properties file (application-integrationTest.properties):
- Configure the JDBC url by using the following format:
jdbc:tc:postgresql:[database version]://[host]:[port]/[database name]. - Ensure that our Spring Boot application uses the JDBC driver provided by TestContainers (
org.testcontainers.jdbc.ContainerDatabaseDriver).
After we have configured our database connection, the application-integrationTest.properties file looks as follows:
1spring.datasource.type=com.zaxxer.hikari.HikariDataSource
2spring.datasource.url=jdbc:tc:postgresql:12.1:///integrationTest
3spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
4
5#I18N
6spring.messages.basename=i18n/messages
7
8#Liquibase Configuration
9spring.liquibase.change-log=classpath:/db/changelog/db.changelog.xml
Next, we will learn to configure our integration tests.
Configuring Our Integration Tests
We can configure our integration tests by following these steps:
First, because we want to eliminate duplicate configuration code from our integration tests, we have to create a custom annotation that contains the configuration which is shared by our integration tests. We can create this annotation by following these steps:
- Create a new annotation class.
- Ensure that our custom annotation can be applied to a test class.
- Ensure that our custom annotation is stored in binary output and is visible for reflection.
- Ensure that our custom annotation is included in the documentation that’s generated from our test classes.
- Ensure that our integration tests load the application context of our Spring Boot application and enable the testing enhancements provided by Spring Boot.
- Integrate DbUnit with the Spring TestContext framework.
- Configure the active Spring profile. Note that our integration tests must use a Spring profile called:
integrationTest. - Mark our test class as an integration test class by using the JUnit 5 tag:
integrationTest.
After we have created the @DatabaseIntegrationTest annotation, its source code looks as follows:
1import com.github.springtestdbunit.DbUnitTestExecutionListener
2import org.junit.jupiter.api.Tag
3import org.junit.jupiter.api.extension.ExtendWith
4import org.springframework.boot.test.context.SpringBootTest
5import org.springframework.test.context.ActiveProfiles
6import org.springframework.test.context.ContextConfiguration
7import org.springframework.test.context.TestExecutionListeners
8import org.springframework.test.context.junit.jupiter.SpringExtension
9
10@Target(AnnotationTarget.CLASS)
11@Retention(AnnotationRetention.RUNTIME)
12@MustBeDocumented
13@SpringBootTest
14@TestExecutionListeners(
15 listeners = [DbUnitTestExecutionListener::class],
16 mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
17)
18@ActiveProfiles("integrationTest")
19@Tag("integrationTest")
20annotation class DatabaseIntegrationTest
Second, when we create a new test class which contains integration tests for a repository, we have to annotate the test class with the @DatabaseIntegrationTest annotation.
After we have done this, the source code of our test class looks as follows:
1@DatabaseIntegrationTest
2class RepositoryTest {
3}
We can now start the PostgreSQL database before our integration tests are run, and we know how we can configure our integration tests without writing any duplicate code. Let’s summarize what we learned from this lesson.
Summary
This lesson has taught us two things:
- If we want that TestContainers starts a PostgreSQL database before our integration tests are run, we have to use the JDBC driver provided by TestContainers and configure our data source url by using a special format.
- Because we want to configure our integration tests without writing duplicate configuration code, we have to create a custom annotation that contains the configuration which is shared by our integration tests.