3

我目前正在尝试更改测试代码中的一些 Spring 配置属性(它们不是静态的,这就是原因)。当我尝试用@ContextConfiguration(initializers = [MyTestClass.Initializer::class]).

MyTestClass我定义了这个:

inner class Initializer : ApplicationContextInitializer<ConfigurableApplicationContext> {
    override fun initialize(applicationContext: ConfigurableApplicationContext) {
        val values = TestPropertyValues.of("spring.datasource.url=" + postgresqlContainer.jdbcUrl)
        values.applyTo(applicationContext)
    }
}

(我在这里使用 Testcontainers ......如何让它工作可能是一个单独的问题,请随时帮助我。) postgresqlContainerMyTestClass我想要访问的成员。当我运行测试时,我得到一个错误:

Caused by: java.lang.IllegalArgumentException: No argument provided for a required parameter: instance of fun com.example.MyTestClass.Initializer.<init>(): com.example.MyTestClass.Initializer

嗯,好的,所以我一直在调试,我认为是 SpringBeanUtils无法处理 Kotlin 内部类。如果我inner从内部类中删除关键字 BeanUtils 可以创建一个实例——当然这对我没有帮助,因为我需要访问外部类的属性。

我写了一个小测试来证明我的怀疑:

import io.kotlintest.specs.StringSpec
import org.springframework.beans.BeanUtils

class Thing {
    inner class InnerThing {

    }
}

class BeanUtilTest: StringSpec({
    "instantiate inner class" {
        BeanUtils.instantiateClass(Thing.InnerThing::class.java)
        // fails :-(
    }
})

问题:有解决方法吗?如何在 Kotlin 的测试中覆盖应用程序属性?

4

1 回答 1

1

我只是遇到了这个问题,经过很长时间试图弄清楚发生了什么,我终于想出了一个解决方案。

您可以按如下方式使用伴随对象(例如,对于 MySql):

@Testcontainers
@ExtendWith(SpringExtension::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(initializers = [ExampleIntegrationTest.Companion.Initializer::class])
class ExampleIntegrationTest {

    companion object {

        @Container
        @JvmField
        val mySqlContainer = KotlinMySqlContainer()

        class Initializer : ApplicationContextInitializer<ConfigurableApplicationContext> {
            override fun initialize(configurableApplicationContext: ConfigurableApplicationContext) {

                TestPropertyValues.of(
                    "spring.datasource.url=" + mySqlContainer.jdbcUrl,
                    "spring.datasource.username=" + mySqlContainer.username,
                    "spring.datasource.password=" + mySqlContainer.password
                ).applyTo(configurableApplicationContext.environment)
            }
        }
    }
    ...
}
于 2019-10-08T03:21:44.150 回答