Как внедрить переопределения тестов в график зависимостей по умолчанию?

#android #kotlin #kodein

#Android #kotlin #kodein

Вопрос:

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

  • Мое приложение использует KodeinAware класс приложения. Обслуживаемый экземпляр Kodein содержит все зависимости, требуемые моим приложением.
  • В своих тестах я хотел бы внедрить переопределенные переопределения для определенных зависимостей, чтобы проверить поведение приложения в различных ситуациях.
  • Переопределения должны быть разными для каждого теста и должны вводиться до / во время выполнения теста.

Является ли настраиваемое расширение Kodein разумным в этой ситуации или существует более простой и более подходящий подход (и если да, то какой)?

Ответ №1:

Если вашему тесту предоставлен Kodein экземпляр (это означает, что он может использовать Kodein объект, отличный от вашего Application ), то рекомендуемый подход заключается в создании нового объекта Kodein, который расширяет объект приложения и переопределяет все необходимые привязки.

 val testKodein = Kodein {
    extend(appKodein())

    bind<MyManager>(overrides = true) with singleton { mock<MyManager>() }
}
  

Настраиваемый параметр Kodein рекомендуется использовать только в том случае, если вы используете статический «один истинный кодейн». Его использование исключает возможность параллельного запуска ваших тестов (поскольку все они обращаются к одному и тому же экземпляру Kodein) и заставляет вас переходить clear ConfigurableKodein между каждым тестированием и повторно объявлять каждый раз разные переопределения.

Комментарии:

1. Я использую этот подход в своих модульных тестах, то есть в тестах, которые проверяют правильное поведение введенных классов. Однако в моем инструментарии, точнее, в моих функциональных тестах, я тестирую экземпляр моего реального приложения. Чтобы сделать тесты детерминированными, я заменяю определенные зависимости в своем графике на mocks . Кодеин предоставляется Application экземпляром, следовательно, он похож на «единственный истинный кодеин». Прямо сейчас я тестирую настраиваемый подход kodein и вернусь, как только у меня будут некоторые результаты.

Ответ №2:

Теперь я использую ConfigurableKodein внутренний пользовательский App класс.

 class App : Application(), KodeinAware {
    override val kodein = ConfigurableKodein()

    override fun onCreate() {
        super.onCreate()

        // A function is used to create a Kodein module with all app deps.
        kodein.addImport(appDependencies(this))
    }
}

// Helper for accessing the App from any context.
fun Context.asApp() = this.applicationContext as App
  

Внутри моего AppTestRunner класса я объявляю конфигурацию изменяемой. Таким образом, я могу сбросить его конфигурацию между каждым тестом.

 class AppTestRunner : AndroidJUnitRunner() {
    override fun callApplicationOnCreate(app: Application) {
        app.asApp().kodein.mutable = true
        super.callApplicationOnCreate(app)
    }
}
  

Я создал правило JUnit, которое сбрасывает график зависимостей перед каждым тестом.

 class ResetKodeinRule : ExternalResource() {
    override fun before() {
        val app = InstrumentationRegistry.getInstrumentation().targetContext.asApp()
        app.kodein.clear()
        app.kodein.addImport(appDependencies(app))
    }
}
  

Теперь в моих тестах я могу извлечь App.kodein экземпляр и внедрить макеты, которые переопределяют зависимости исходного графика. Единственное, что нужно гарантировать, это то, что тестируемая активность запускается после настройки mocks, или поведение не предсказуемо.