В настоящее время я пытаюсь изменить некоторые свойства конфигурации 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 ... как заставить эту работу работать, это может быть отдельный вопрос, не стесняйтесь мне помочь.)
postgresqlContainer - член MyTestClass, к которому я хочу получить доступ. Когда я запускаю тест, я получаю сообщение об ошибке:
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 из своего внутреннего класса, 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)
}
}
}
...
}