我正在尝试寻找正确的方法来覆盖Espresso测试中的 Component 或 Module ,同时使用最新的Dagger2 @ strong。@ Component.Factory 功能。 我有以下组件定义:
@Component(
modules = [SomeModule::class],
dependencies = [SessionComponent::class]
)
interface MainComponent {
@Component.Factory
interface Factory {
fun create(sessionComponent: SessionComponent): MainComponent
}
}
和 SomeModule 的定义是:
@Module
object SomeModule {
@Provides
@JvmStatic
fun some(): Some = SomeImpl()
}
一些是一个接口, SomeImpl 将是其实现。
现在,要加入我们的活动,我们要做:
DaggerMainComponent.factory().create(sessionComponent).inject(this)
我们使用 CustomApp:应用程序
中声明的扩展功能解析 sessionComponentval Context.sessionComponent: SessionComponent
get() = App.sessionComponent(this)
现在按照官方指南中的建议进行:https://dagger.dev/testing,我们应该尝试将 MainComponent 替换为 TestMainComponent ,该组件将具有 TestSomeModule 和我们的测试实现。
我最初的想法是朝这个方向发展: 从活动中删除注入,并用将执行此注入的 Injector 对象代替。另外,修改 create()方法并传递 Module :
DaggerMainComponent.factory().create(sessionComponent).inject(this)
已移至:
object Injector {
@VisibleForTesting
var someModule: SomeModule = SomeModule()
fun inject(activity: Activity) {
when (activity) {
is MainActivity -> {
DaggerMainComponent.factory().create(App.sessionComponent(activity), someModule).inject(activity)
}
}
}
}
以及新的 Factory 定义:
@Component.Factory
interface Factory {
fun create(sessionComponent: SessionComponent, someModule: SomeModule): MainComponent
}
然后,在活动中的 onCreate()之后,我们只需调用Injector.inject(this)
其背后的想法是,在UI测试中我们可以做到:
@Before
fun setup() {
Injector.someModule = TestSomeModule
}
并以这种方式更改实现。由于 SomeModule 这是一个单例对象,因此我们无法扩展。
这导致我采用以下方法: 该应用程序具有版本和调试 buildTypes 。在release和debug文件夹中,我具有 Injector 的真实实现( MainComponent 引用了 SomeModule )。 然后在 androidTest 文件夹中,我有另一个 Injector 对象,但具有以下内容:
object Injector {
fun inject(activity: Activity) {
when (activity) {
is MainActivity -> {
DaggerTestMainComponent.factory().create(App.sessionComponent(activity)).inject(activity)
}
}
}
}
和 TestMainComponent 是
@Component(
modules = [TestSomeModule::class],
dependencies = [SessionComponent::class]
)
interface TestMainComponent {
@Component.Factory
interface Factory {
fun create(sessionComponent: SessionComponent): TestMainComponent
}
}
@Module
object TestSomeModule {
@Provides
@JvmStatic
fun greeter(): Some = TestSomeImpl()
}
这种方法有效,并且gradle用androidTest文件夹中的一个替换了debug文件夹中的 Injector 对象,但是,我想知道是否有更好的方法来避免使用两个 Injector 对象,或者只是更新与测试对象一起使用的 Module 。 任何建议都欢迎!