首页 > 解决方案 > 带有 testcontainers 和 jOOQ 的 Spring Boot 不会注入 DSL 上下文

问题描述

我对 spring boot + jOOQ 和 testcontainers 有一些问题。DSL 上下文不会注入我的测试类。

我做了一些准备使用SQLContainer

class SpringTestContainer: PostgreSQLContainer<SpringTestContainer> {

    private val postgreSqlPort = 5432
    private val db = "m4"

    companion object {
        var instance: SpringTestContainer? = null

        fun get(): SpringTestContainer {
            if(instance == null) {
                instance = SpringTestContainer()
            }

            return instance!!
        }
    }

    override fun getDatabaseName(): String = db

    constructor() : this("registry.dev.tskad.stdev.ru/m4/db:latest")

    constructor(dockerImageName: String) : super(dockerImageName){
        withImagePullPolicy(PullPolicy.alwaysPull())
        addExposedPort(postgreSqlPort)
        waitStrategy = LogMessageWaitStrategy()
            .withRegEx(".*database system is ready to accept connections.*\\s")
            .withTimes(1)
            .withStartupTimeout(Duration.of(30, ChronoUnit.SECONDS))
    }

    override fun getJdbcUrl(): String {
        return String.format("jdbc:postgresql://%s:%d/%s", containerIpAddress, getMappedPort(postgreSqlPort), databaseName)
    }

    override fun waitUntilContainerStarted() {
        getWaitStrategy().waitUntilReady(this)
    }

    override fun getLivenessCheckPorts(): Set<Int?> {
        return HashSet(getMappedPort(postgreSqlPort))
    }

}

然后我创建了一些抽象来扩展我的集成测试类

@ContextConfiguration(initializers = [SpringIntegrationTest.Initializer::class])
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@JooqTest
abstract class SpringIntegrationTest {

    @get:Rule
    var postgreSQLContainer = SpringTestContainer.get()

    inner class Initializer: ApplicationContextInitializer<ConfigurableApplicationContext> {
        override fun initialize(applicationContext: ConfigurableApplicationContext) {
            with(applicationContext.environment.systemProperties) {
                put("spring.datasource.url", postgreSQLContainer.jdbcUrl)
                put("spring.datasource.username", postgreSQLContainer.username)
                put("spring.datasource.password", postgreSQLContainer.password)
            }
        }
    }

}

然后我实现了测试类

@ExtendWith(SpringExtension::class)
class TransactionRepositoryImplTest: SpringIntegrationTest() {

    @Autowired
    private var dslContext: DSLContext? = null

    private var transactionRepository: TransactionRepository? = null

    @Before
    fun setUp() {
        assertThat(dslContext).isNotNull
        transactionRepository = TransactionRepositoryImpl(dslContext!!)
    }

    @After
    fun tearDown() {

    }

    @Test
    fun findTransactionData() {
        transactionRepository?.findTransactionByVehicleUuid(null).apply {
            assertNull(this)
        }

    }

}

当我开始这个类的测试时 - 测试失败,因为断言没有通过。这是测试报告https://pastebin.com/0HeqDcCT

所以..怎么不可能?我看到了一些关于这个堆栈的指南(Spring/jOOQ/TestContainers)。他们都在工作。也许我错过了一些测试依赖项?如果您有此案例的经验 - 请分享您的解决方案。我将不胜感激。

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("org.springframework.boot:spring-boot-starter-jooq")
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    implementation("org.springframework.cloud:spring-cloud-starter-consul-config")
    implementation("org.springframework.cloud:spring-cloud-stream")
    implementation("org.springframework.cloud:spring-cloud-stream-binder-kafka")
    implementation("org.springframework.kafka:spring-kafka")
    implementation("org.springframework.boot:spring-boot-starter-amqp")
    implementation ("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.3")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.10.3")
    runtimeOnly("org.postgresql:postgresql:42.2.12")
    jooqGeneratorRuntime("org.postgresql:postgresql:42.2.12")
    annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
    testImplementation("org.springframework.boot:spring-boot-starter-test") {
        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
        exclude(module = "junit")
    }
    testImplementation("com.ninja-squad:springmockk:2.0.1")
    testImplementation("org.springframework.cloud:spring-cloud-stream-test-support")
    testImplementation("org.springframework.kafka:spring-kafka-test")
    testImplementation("org.springframework.amqp:spring-rabbit-test")
    testImplementation("org.testcontainers:postgresql:1.14.3")
}

标签: spring-bootkotlinjooqspring-boot-testtestcontainers

解决方案


我可能遗漏了一些东西,但在那个设置中,你必须在 postgreSQLContainer.start()某个地方手动运行。例如,它可以在@BeforeAll.


推荐阅读