mardi 26 février 2019

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?





Aucun commentaire:

Enregistrer un commentaire