如何使用 Koin 注入 @BeforeClass 静态方法?

How can I use Koin to inject in a @BeforeClass static method?

我有一个集成测试需要在任何后续测试 运行 之前调用 REST 服务来获取一次访问令牌。在将 Koin 添加到我的项目之前,我在一个用 @BeforeClass 注释的静态方法中完成了此操作,如下所示:

class PersonRepositoryIntegrationTest {

    companion object {
        private var _clientToken: String? = null

        @BeforeClass
        @JvmStatic
        fun setup() {
            _clientToken = AuthRepository().getClientToken()!!.accessToken
        }
    }

    @Test
    fun testCreatePerson() {
        PersonRepository().createPerson(_clientToken)
    }

AuthRepository 和 PersonRepository 有额外的依赖关系,到目前为止,这些依赖关系是在它们的构造函数中实例化的。现在,我想使用 Koin 通过注入存储库来解决这些依赖关系:

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
        }
    }

当我尝试在伴随对象中使用 inject 时,编译器给出错误:

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

有没有其他方法可以使用 Koin 在像这样的 @BeforeClass 静态方法中注入我的 类?

根据 kotlin documentation,伴侣对象在技术上是真实的对象。

even though the members of companion objects look like static members in other languages, at runtime those are still instance members of real objects, and can, for example, implement interfaces:

如果 class 想要注入依赖项并且它不是支持的 koin 之一 classes(Activity、Fragment、ViewModel、KoinTest 等),那么 class 应该实现 KoinComponent 接口。

因此请考虑将您的伴生对象定义更改为以下内容,然后重试。

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
        }

除了已接受的答案外,我发现我可以使用 org.koin.java.standalone.KoinJavaComponent 中的 inject 方法,记录在案 here:

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
        }
    }

这对我来说似乎很奇怪,因为我在 Kotlin class 中使用 Java 互操作方法,所以我更愿意通过更改我的伴随对象来扩展 KoinComponent 来解决问题,而不是推荐 .