We have a Spring Boot project written in kotlin (for the first time) where we want to try kotlintest for writing tests.
Our datasource is a postgresql database, and in our tests we utilize org.testcontainers:postgresql
in order to not use a separate datasource like h2, or having to use a test schema in our actual database. Since firing up a testcontainer is a somewhat lengthy operation, we want it to only be done once across multiple tests.
We use liquibase to evolve the database schema.
So with that in mind we created an abstract class ContainerDatabaseTest
which other tests can extend from:
class KPostgresContainer(imageName: String) : PostgreSQLContainer<KPostgresContainer>(imageName)
@ContextConfiguration(initializers = [ContainerDatabaseTest.Initializer::class])
abstract class ContainerDatabaseTest {
companion object {
val container: KPostgresContainer = KPostgresContainer("postgres:9.6.15")
.withDatabaseName("ic_orders_testcontainer_test")
.withUsername("ic_orders")
.withPassword("ic_orders")
init {
container.start()
}
}
class Initializer : ApplicationContextInitializer<ConfigurableApplicationContext> {
override fun initialize(configurableApplicationContext: ConfigurableApplicationContext) {
val values = TestPropertyValues.of(
"spring.datasource.url=${container.jdbcUrl}",
"spring.datasource.username=${container.username}",
"spring.datasource.password=${container.password}",
"spring.liquibase.user=${container.username}",
"spring.liquibase.password=${container.password}"
)
values.applyTo(configurableApplicationContext)
}
}
}
This fires up a testcontainer, once across all the tests that extend it during the test run.
This is then used e.g. like this using JUnit5
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class RepositoriesTests @Autowired constructor(
val em: TestEntityManager,
val moveOrderPlacementRepository: MoveOrderPlacementRepository
) : ContainerDatabaseTest() {
@Test
fun `Persist an object to database`() {
em.persist(someObject)
But how can I rewrite these tests to kotlintest
? In kotlintest you extend from a Spec (abstract class
as well), and in kotlin you cannot extend from multiple classes as far as I understand.
So how would I go about porting this test to kotlintest
? I thought about beforeAll
or afterAll
in ProjectConfig
, but I don't want or need a testcontainer for all tests, only those that requires a datasource. Then there is the TestListener
concept described in the reference, but I struggle to rewrite to that as well.
Any pointers? Thanks!