Как я могу использовать Koin для внедрения в статический метод @BeforeClass? - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть интеграционный тест, который должен вызвать службу 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 статический метод, подобный этому?

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

В дополнение к принятому ответу я обнаружил, что могу использовать метод inject из org.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
        }
    }

Мне это кажется странным, потому что я использую методы взаимодействия Java в классе Kotlin, поэтому я предпочел бы решить эту проблему, изменив вместо этого объект-компаньон, чтобы расширить KoinComponent, как рекомендовано здесь .

0 голосов
/ 20 февраля 2019

Согласно документации 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
        }
...