1

我目前正在阅读这篇文章,尝试使用 Kotlin 在 android 中模拟 dagger 依赖项,但遇到了一些麻烦。

我收到一条错误消息,提示 activityInjector 未初始化。

我究竟做错了什么?

测试应用组件

@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
    }
}

测试应用

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()
}
4

2 回答 2

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()) 
}
于 2018-12-16T07:20:56.807 回答
1

在应用源的 onCreate 处创建一个 dagger 组件

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)
}
于 2018-12-14T02:54:35.197 回答