Тестирование пользовательского интерфейса Android для архитектуры MVVM с Dagger2, Espresso и Mockito - PullRequest
0 голосов
/ 27 февраля 2019

Я пытаюсь добавить тесты пользовательского интерфейса в приложение в первый раз, и я смотрел на использование эспрессо.

Приложение использует Dagger2 для DI с @Inject аннотациями для классов, которые должны быть введеныи AndroidInjection / AndroidSupportInjection на экранах (активность / фрагмент).

class Application : android.app.Application(), HasActivityInjector, HasServiceInjector {
...
    override fun onCreate() {
        super.onCreate()
        initDagger()
        Timber.d("Application initialized successfully!")
    }

    protected open fun initDagger() {
        Components.initialize(this)
    }
}

object Components : ComponentFactory {
    private lateinit var sComponent: AppComponent

    fun initialize(app: Application) {
         sAppComponent = DaggerAppComponent.builder()
            .applicationModule(ApplicationModule(this))
            .build()
    }
    // overrides
}

interface ComponentFactory {
    fun app(): AppComponent
    fun authenticated(): AuthenticatedComponent
}

Далее Component s и Module s.AppActivitiesModule и AuthenticatedActivitiesModule - это классы с @ContributesAndroidInjector для экранов.

@Singleton
@Component(modules = [AppModule::class, AppActivitiesModule::class, AndroidInjectionModule::class, AndroidSupportInjectionModule::class])
interface AppComponent {

    fun authenticatedComponentBuilder(): AuthenticatedComponent.Builder

    fun inject(app: Application)

    @Component.Builder
    interface Builder {
        fun build(): AppComponent

        fun applicationModule(applicationModule: ApplicationModule): Builder
    }
}

@Module
open class AppModule(private val application: Application) {
// some @Provides
}
@AuthenticatedScope
@Subcomponent(modules = [AuthenticatedModule::class, AuthenticatedActivitiesModule::class])
interface AuthenticatedComponent {

    fun inject(application: Application)

    @Subcomponent.Builder
    interface Builder {
        fun userModule(module: UserModule): Builder

        fun build(): AuthenticatedComponent
    }
}


@Module
class AuthenticatedModule(private val userId: Long,
                          private val userRole: User.Role) {
// Some @Provides @AuthenticatedScope
}

И типичный вариант использования:

@Singleton
class AppLevelService 
@Inject constructor(...) { ... }

@AuthenticatedScope
class AuthenticatedLevelServices 
@Inject constructor(...) { ... }

class ViewModel 
@Inject constructor(private val appService: AppLevelService,
                    private val authService: AuthenticatedLevelServices) { ... }

class MyActivity : BaseActivity {
    @Inject 
    lateinit var vmProvider: Provide<ViewModel>

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
    }
}

Как я могу сделатьтестовая установка для этого «типа» использования кинжала?

Я нахожу множество примеров тестирования с помощью dagger2, но для аннотаций @Provides, и я думаю, что должен быть способ смоделировать инъекционные классы с помощью@Inject.

Я пробовал DaggerMock, но я получаю:

Вы должны определить переопределенные объекты, используя аннотированный метод @Provides вместо использования аннотации @Inject

Не то чтобы это могло на что-то повлиять, но я также использую пользовательский Runner с DexOpener.

Любые идеи или хорошая документация / примеры для тестирования этой установки?

...