【问题标题】:How can I use Koin to inject in a @BeforeClass static method?如何使用 Koin 注入 @BeforeClass 静态方法?
【发布时间】:2019-02-07 16:30:37
【问题描述】:

我有一个集成测试,需要在运行任何后续测试之前调用 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 静态方法中注入我的类吗?

【问题讨论】:

    标签: junit kotlin dependency-injection static koin


    【解决方案1】:

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

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

    如果一个类想要注入依赖并且它不是 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
            }
    

    【讨论】:

      【解决方案2】:

      除了接受的答案,我发现我可以使用来自 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 类中使用 Java 互操作方法,所以我更愿意通过更改我的伴随对象来扩展 KoinComponent 来解决问题,而不是按照推荐的 here

      【讨论】:

        猜你喜欢
        • 2019-01-07
        • 1970-01-01
        • 2015-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-25
        • 1970-01-01
        相关资源
        最近更新 更多