Кинжал не вводит активность

В настоящее время я работаю над этой статьей, пытаясь смоделировать зависимости от кинжалов в Android с Kotlin, но у меня возникли некоторые проблемы.

Я получаю сообщение об ошибке, указав, что ActivityInjector не инициализирован.

Что я делаю неправильно?

TestAppComponent

@Singleton
@Component(
    modules = [
        AndroidSupportInjectionModule::class,
        TestAppModule::class,
        ActivityModule::class,
        FragmentModule::class,
        ViewModelModule::class
    ]
)
interface TestAppComponent : AndroidInjector<TestApp> {

    @Component.Builder
    abstract class Builder : AndroidInjector.Builder<TestApp>() {
        abstract fun appModule(appModule: TestAppModule): Builder
    }
}

TestApp

class TestApp: Application(), HasActivityInjector {

    @Inject
    lateinit var activityInjector: DispatchingAndroidInjector<Activity>

    override fun activityInjector(): AndroidInjector<Activity>  = activityInjector
}

Тестовый инжектор

class TestInjector(private val testAppModule: TestAppModule) {

    fun inject() {
        val testApp= ApplicationProvider.getApplicationContext() as TestApp

        DaggerTestAppComponent
            .builder()
            .appModule(testAppModule)
            .create(testApp)
            .inject(testApp)
    }
}

Модуль деятельности

@Module
abstract class ActivityModule {
    @ContributesAndroidInjector
    abstract fun provideNavigationActivity(): NavigationActivity
}

Инструментальный юнит-тест

@Rule
@JvmField
var navigationActivityTestRule = ActivityTestRule(NavigationActivity::class.java, true, true)

@MockK
private lateinit var repo: Repo

@Before
fun setUp() {
    MockKAnnotations.init(this)

    TestInjector(TestAppModule(repo)).inject()
}

2 ответа

Решение

Из-за ActivityTestRule ваша деятельность запускается еще до TestInjector вызывается из вашего метода установки. Вам нужно отложить запуск активности до DaggerTestAppComponent построено.

Попробуй это:

@Rule
@JvmField
var navigationActivityTestRule = ActivityTestRule(NavigationActivity::class.java, true, false) 
// ^^ Notice the third parameter here, passing false will not launch the activity

@MockK
private lateinit var repo: Repo

@Before
fun setUp() {
    MockKAnnotations.init(this)
    TestInjector(TestAppModule(repo)).inject()

    // Launch the activity now that TestInjector is called
    navigationActivityTestRule.launchActivity(Intent()) 
}

Создайте компонент кинжала в onCreate вашего исходного кода приложения

class TestApp: Application(), HasActivityInjector {

    @Inject
    lateinit var activityInjector: DispatchingAndroidInjector<Activity>

    override fun onCreate() {
        super.onCreate()
        DaggerTestAppComponent.builder()
            .application(this)
            .build()
            .inject(this)
    }

    override fun activityInjector(): AndroidInjector<Activity>  = activityInjector
}

и изменение компонента, как это

@Singleton
@Component(
    modules = [
        AndroidSupportInjectionModule::class,
        TestAppModule::class,
        ActivityModule::class,
        FragmentModule::class,
        ViewModelModule::class
    ]
)
interface TestAppComponent{

    @Component.Builder
    interface Builder{
        @BindsInstance fun application(app: TestApp): Builder
        fun build(): TestAppComponent
    }

    fun inject(app: TestApp)
}
Другие вопросы по тегам