3

我有一个集成测试,需要在运行任何后续测试之前调用 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

@BeforeClass还有另一种方法可以使用 Koin 以这样的静态方法注入我的类吗?

4

2 回答 2

7

根据 kotlin文档,伴生对象在技术上是真实的对象。

尽管伴生对象的成员在其他语言中看起来像静态成员,但在运行时它们仍然是真实对象的实例成员,并且可以例如实现接口:

如果一个类想要注入依赖项并且它不是 koin 支持的类之一(Activity、Fragment、ViewModel、KoinTest 等),那么该类应该实现 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
        }
于 2019-02-20T09:58:57.220 回答
0

除了接受的答案之外,我发现我可以使用injectorg.koin.java.standalone.KoinJavaComponent 中的方法,记录在这里

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 类中使用 Java 互操作方法,所以我更愿意通过更改我的伴随对象来扩展 KoinComponent 来解决问题,而不是按照这里的建议。

于 2019-02-21T15:26:16.433 回答