reflection - Kotlin reflection change instance and all members that use the instance
问题描述
We are using reflection to enable our tests to be started in different environments.
A typical test would look like this:
class TestClass {
val environment: Environment = generateEnvironment("jUnit")
val path: String = environment.path
//Do test stuff
}
We are using reflection like this:
class PostgresqlTest{
val classList: List<KClass<*>> = listOf(TestClass::class)
val postgresEnv = generateEnvironment("postgres")
@TestFactory
fun generateTests(): List<DynamicTest> = classList.flatMap { testClass ->
val instance = testClass.createInstance()
environmentProperty(testclass).setter.call(instance, postgresEnv)
//<<generate the dynamic tests>>
}
fun environmentProperty(testClass: KClass<*>) =
testClass.memberProperties.find {
it.returnType.classifier == Environment::class
} as KMutableProperty<*>
}
Now we have the issue that path != environment.path
in the PostgresqlTest
I know this can be solved in the TestClass with lazy or get() like this
class TestClass {
val environment: Environment = generateEnvironment("jUnit")
val path: String by lazy { environment.path }
// OR
val path: String get() = environment.path
}
However this seems like a potential pitfall for future developers, especially since the first code snippet will work in TestClass and only fail for the tests where the environment is overwritten.
What is the cleanest way to ensure that path == environment.path
when overwritting the property?
解决方案
我最终在 gradle 中为每个环境创建了一个新的测试任务:
task postgresqlIntegrationTest(type: Test, group: "Verification", description: "Runs integration tests on postgresql.") {
dependsOn compileTestKotlin
mustRunAfter test
environment "env", "postgresql"
useJUnitPlatform {
filter {
includeTestsMatching "*IT"
}
}
}
我的测试类只是像这样加载环境:
class TestClass {
val environment: Environment = generateEnvironment(System.getenv("env") ?: "junit")
//Do test stuff
}
推荐阅读
- javascript - 您可以在 google api 上的标记上将图像添加到内容框吗?
- java - 我无法在 recyclerview 上显示浮动操作菜单
- r - R中的奇偶一致性
- laravel - Laravel 5.x 和 7.x 认证中间件的区别
- javascript - 图像数组 ReactJs 响应式轮播
- sql-server - SQL CLR 中的 .Net Core 程序集
- scheme - 评估复合程序元循环“应用”的顺序
- apache-nifi - 在“ExtractText”调用的 Nifi 处理器“InvokeHttp”中,您在哪里编写 POST 请求的正文
- android - 调试 espresso 测试在“实例化测试...”处挂起并出现 Object.wait 错误
- python - Python (cpython) 在内存屏障和原子性等方面的行为是否得到保证?