Tengo una prueba de integración que necesita llamar a un servicio REST para obtener un token de acceso una vez antes de que se ejecuten las pruebas posteriores. Antes de agregar Koin a mi proyecto, logré esto en un método estático anotado con @BeforeClass así:
class PersonRepositoryIntegrationTest { companion object { private var _clientToken: String? = null @BeforeClass @JvmStatic fun setup() { _clientToken = AuthRepository().getClientToken()!!.accessToken } } @Test fun testCreatePerson() { PersonRepository().createPerson(_clientToken) }AuthRepository y PersonRepository tienen dependencias adicionales que hasta ahora se instanciaban en sus constructores. Ahora, quiero usar Koin para resolver estas dependencias inyectando los repositorios:
class PersonRepositoryIntegrationTest : KoinTest { companion object { private val _authRepository by inject<IAuthRepository>() private val _personRepository by inject<IPersonRepository>() private var _clientToken: String? = null @BeforeClass @JvmStatic fun beforeClass() { startKoin(listOf(AppModule.appModule)) _clientToken = _authRepository.getClientToken()!!.accessToken } } Cuando trato de usar inject dentro del objeto complementario, el compilador da un error:
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch. * public inline fun <reified T : Any> KoinComponent.inject(name: String = ..., scope: Scope? = ..., noinline parameters: ParameterDefinition = ...): Lazy<IAuthRepository> defined in org.koin.standalone ¿Hay otra forma en que pueda usar Koin para inyectar mis clases en un método estático @BeforeClass como este?
Según la documentación de Kotlin, los objetos complementarios son técnicamente objetos reales.
aunque los miembros de los objetos complementarios parecen miembros estáticos en otros lenguajes, en tiempo de ejecución siguen siendo miembros de instancia de objetos reales y pueden, por ejemplo, implementar interfaces:
Si una clase quiere inyectar dependencias y no es una de las clases compatibles con koin (Actividad, Fragmento, ViewModel, KoinTest, etc.), entonces esa clase debería implementar la interfaz KoinComponent.
Por lo tanto, considere cambiar la definición de su objeto complementario a la siguiente y vuelva a intentarlo.
companion object : KoinComponent{ private val _authRepository by inject<IAuthRepository>() private val _personRepository by inject<IPersonRepository>() private var _clientToken: String? = null @BeforeClass @JvmStatic fun beforeClass() { startKoin(listOf(AppModule.appModule)) _clientToken = _authRepository.getClientToken()!!.accessToken }Además de la respuesta aceptada, descubrí que puedo usar el método de inject de org.koin.java.standalone.KoinJavaComponent, documentado aquí :
import org.koin.java.standalone.KoinJavaComponent.inject class PersonRepositoryIntegrationTest : KoinTest { companion object { private val _authRepository by inject(IAuthRepository::class.java) private val _personRepository by inject(IPersonRepository::class.java) private var _clientToken: String? = null @BeforeClass @JvmStatic fun beforeClass() { startKoin(listOf(AppModule.appModule)) _clientToken = _authRepository.getClientToken()!!.accessToken } }Esto me parece extraño porque estoy usando métodos de interoperabilidad de Java en una clase de Kotlin, por lo que preferiría resolver el problema cambiando mi objeto complementario para extender KoinComponent en su lugar, como se recomienda aquí .