关于junit:如何使用Koin注入@BeforeClass静态方法?

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

我有一个集成测试,需要在运行任何后续测试之前调用一次REST服务以获得访问令牌。 在将Koin添加到我的项目之前,我是通过一个用@BeforeClass注释的静态方法来实现的,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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通过注入存储库来解决这些依赖关系:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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时,编译器给出了一个错误:

1
2
3
4
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文档,伴随对象在技术上是真实的对象。

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:

如果一个类想注入依赖关系,并且不是koin支持的类之一(Activity,Fragment,ViewModel,KoinTest等),则该类应实现KoinComponent接口。

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

1
2
3
4
5
6
7
8
9
10
11
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方法,在此处记录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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来解决该问题,而不是按照此处的建议。