匕首未注入活动

时间:2018-12-14 01:45:58

标签: android kotlin dagger-2 dagger mockk

我目前正在通过此article进行工作,尝试使用Kotlin在android中模拟dagger依赖性,但是遇到了一些麻烦。

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

我在做什么错了?

TestAppComponent

Boston Public Library

TestApp

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

2 个答案:

答案 0 :(得分:1)

在应用程序源的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)
}

答案 1 :(得分:1)

由于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()) 
}