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

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

  • Мое приложение использует KodeinAware класс приложения. Обслуживаемый экземпляр 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 экземпляры экземпляров и инъекций, которые переопределяют зависимости исходного графа. Единственное, что должно быть гарантировано, - это то, что тестируемое действие запускается после настройки ложных срабатываний, или поведение непредсказуемо.

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

val testKodein = Kodein {
    extend(appKodein())

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

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

Другие вопросы по тегам