我目前正在通过此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
}
答案 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())
}