Как протестировать DaggerFragment с помощью FragmentScenario?

У меня простой Fragment вот так:

class SomeFragment : DaggerFragment() {
    ...
}

Теперь я хочу это проверить Fragment с помощью FragmentScenario

class LoginFragmentTest {

    @Test
    fun test() {
        launchFragmentInContainer<SomeFragment>()
        onView(withId(R.id.someButton))
            .check(matches(isDisplayed()))
    }

}

Но каждый раз, когда я пытаюсь проверить это, всегда:

java.lang.IllegalArgumentException: для <... SomeFragment>инжектор не найден

Как правильно запустить тест? Кто-нибудь может мне здесь помочь?

1 ответ

Решение

Я нашел два способа решения проблемы:

Я считаю первый подход более чистым и рекомендую использовать его, а не второй, но я опишу оба из них, чтобы вы могли сделать свой собственный выбор.


Создавайте ароматы с typealias

  1. Создайте два вкуса продукта, mock а также prod:

app/build.gradle

android {
    ...
    productFlavors {
        prod
        mock {
            applicationIdSuffix '.mock'
        }
    }
}
  1. Затем установите typealias в зависимости от вкуса назовем это BaseFragment:

prod ароматapp/src/prod/com.example.mypackage/BaseFragment.kt

typealias BaseFragment = DaggerFragment

mock аромат app/src/mock/com.example.mypackage/BaseFragment.kt

typealias BaseFragment = Fragment
  1. И, наконец, используйте BaseFragment псевдоним в ваших фрагментах:
class SomeFragment : BaseFragment() {
   ...
}
  1. Чтобы протестировать код с помощью FragmentScenario переключиться с prod* вариант сборки для mock* one и установите все зависимости, которые должны быть введены где-нибудь в вашем тестовом классе (например, используя mocks)

Своя DaggerFragment и тестовые варианты фрагментов

  1. Создай свой DaggerFragment (на основе фактических dagger.android.support.DaggerFragment реализация):
abstract class DaggerFragment() : Fragment(), HasAndroidInjector {

    @Inject
    lateinit var androidInjector: DispatchingAndroidInjector<Object>

    override fun onAttach(context: Context) {
        injectMembers()
        super.onAttach(context)

    override fun androidInjector(): AndroidInjector<Object> = androidInjector

    protected open fun injectMembers() = AndroidSupportInjection.inject(this)
}
  1. Расширьте свой DaggerFragmentреализация и установить фрагментopen:
open class SomeFragment : DaggerFragment() {
    ...
}
  1. Создайте другую реализацию вашего фрагмента для тестовых целей и переопределите injectMembers метод:
class TestSomeFragment : SomeFragment() {

    override injectMembers() {
        /* you can manually inject dependencies and mocks here */
    }
}
  1. Использовать TestSomeFragment в ваших тестах.
Другие вопросы по тегам