Search code examples
springspring-bootkotlinintegration-testingtestcontainers

Kotlin integration Tests with Spring Boot


What I have: I'm developing a microservice, using Spring Boot with Web and MongoDB as storage. For CI integration tests I use test containers. I have two integrations tests with SpringBootTest annotations, which use TestConfig class. TestConfig class provides setup MongoDB test container with fixed exposed ports.

My problem: When I run my tests one at a time then they succeed. But when I run my tests at the same time then they failed.

MongoContainerConfig.kt

@TestConfiguration
class MongoContainerConfig {

    var mongoContainer: GenericContainer<Nothing>

    constructor() {
        mongoContainer = FixedHostPortGenericContainer<Nothing>("mongo")
                .withFixedExposedPort(27018,27017)
        mongoContainer.start()
    }

    @PreDestroy
    fun close() {
        mongoContainer.stop()
    }
}

First test

@SpringBootTest(
    classes = arrayOf(MongoContainerConfig::class, AssertUtilsConfig::class),
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
class CardControllerTest {

    @Test
    fun test() {}
}

Second test

@SpringBootTest(classes = arrayOf(MongoContainerConfig::class, AssertUtilsConfig::class))
class PositiveTest {

    @Test
    fun test() {}
}

Error msg

Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoContainerConfig': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.lang.card.engcard.config.MongoContainerConfig$$EnhancerBySpringCGLIB$$e58ffeee]: Constructor threw exception; nested exception is org.testcontainers.containers.ContainerLaunchException: Container startup failed
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1320)
    a

This project you can see on github with CI https://github.com/GSkoba/eng-card/runs/576320155?check_suite_focus=true

It's very funny because tests work if rewrite them to java


Solution

  • Hah, it not easy) https://docs.spring.io/spring/docs/5.2.5.RELEASE/spring-framework-reference/testing.html#testcontext-ctx-management-caching Tests have different context and its why MongoContainerConfig call twice. Fix - add webEnv as in CardControllerTest.kt

    @SpringBootTest(classes = arrayOf(MongoContainerConfig::class, AssertUtilsConfig::class),
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    class PositiveTest 
    

    Proof https://github.com/GSkoba/eng-card/actions/runs/78094215