spring-boot - 如何覆盖测试类中的 spring 应用程序属性?使用 Kotlin 内部类时 Spring 的 @ContextConfiguration 中断

标签 spring-boot kotlin testcontainers

我目前正在尝试更改测试代码中的一些 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

嗯,好的,所以我继续调试了一下,我认为是 Spring 的 BeanUtils无法处理 Kotlin 内部类。如果我删除 inner来 self 的内部类 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 测试中覆盖应用程序属性?

最佳答案

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

您可以按如下方式使用伴生对象(例如,对于 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)
            }
        }
    }
    ...
}

关于spring-boot - 如何覆盖测试类中的 spring 应用程序属性?使用 Kotlin 内部类时 Spring 的 @ContextConfiguration 中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53854572/

相关文章:

docker - 在Java内部使用Docker环境变量

java - Spring Boot 安全登录 (v4)

java - 找不到路径 PostgreSQLContainer testContainers

java - GenericContainer 不拾取文件进行处理

java - 在 Spring Boot 中配置安全性

java - 在 jdbcTemplate.update(String sql,Object[] args,int[] argTypes) 和 jdbcTemplate.update(String sql,Object[] args) 之间进行选择

maven - 在 Kscript 中导入库时如何解决 'java.lang.NoClassDefFoundError'?

java - 使用 testcontainer 作为 Dockerfile 的一部分运行测试

android - 有什么方法可以传递@Body 的参数而不是多个@Field

java - android的EditText的动态前导文本