I’m currently trying to change some Spring configuration properties in test code (they aren’t static, that’s why).
There’s this odd thing when I try to solve my problem with @ContextConfiguration(initializers = [MyTestClass.Initializer::class])
.
and in MyTestClass
I defined this:
inner class Initializer : ApplicationContextInitializer<ConfigurableApplicationContext> {
override fun initialize(applicationContext: ConfigurableApplicationContext) {
val values = TestPropertyValues.of("spring.datasource.url=" + postgresqlContainer.jdbcUrl)
values.applyTo(applicationContext)
}
}
(I’m using Testcontainers here... how to get this working might be a separate question, feel free to help me out.)
postgresqlContainer
is a member of MyTestClass
that I want to access. When I run the test I just get an error:
Caused by: java.lang.IllegalArgumentException: No argument provided for a required parameter: instance of fun com.example.MyTestClass.Initializer.<init>(): com.example.MyTestClass.Initializer
Huh, ok, so I kept debugging a bit and I think it’s Spring’s BeanUtils
that isn’t able to handle Kotlin inner classes. If I remove the inner
keyword from my inner class BeanUtils can create an instance – doesn’t help me of course, since I need access to the property of the outer class.
I wrote a little test to assert my suspicion:
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 :-(
}
})
Question: Is there a workaround? How can I override application properties inside my test in Kotlin?