【发布时间】:2021-06-15 22:22:40
【问题描述】:
我正在尝试在使用 Dagger 和 Room 的应用上运行端到端测试,当我运行该应用时,Dagger 无法生成 DaggerTestAppComponent.create()。
我一直在关注Dagger codelab 在测试中实现 Dagger。
这是 Github 上存储库的链接。 https://github.com/Shawn-Nichol/EndToEnd
Step 1. Custom Test Runner
使用自定义测试运行器来使用不同的应用程序类。
class MyCustomTestRunner : AndroidJUnitRunner() {
override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application {
return super.newApplication(cl, MyTestApplication::class.java.name, context)
}
}
Step 2 add to app build gradle.
自定义测试运行器在应用构建 Gradle 中指定。
testInstrumentationRunner "com.example.endtoend.dagger.MyCustomTestRunner"
Step 3 load Modules
TestAppComponent,AndroidTest 范围集的图表。
@Singleton
@Component(modules = [TestSaveDataStorageModule::class, RoomModule::class, DispatchersModule::class])
interface TestAppComponent : AppComponent {
@Component.Factory
interface Factory {
fun create(@BindsInstance context: Context): AppComponent
}
}
Step 4 Add dependencies
为了生成DaggerTestAppComponent kapt 需要作用于androidTest 源集。
dependencies {
...
kaptAndroidTest "com.google.dagger:dagger-compiler:$dagger_version"
}
step 5 update application
我的应用程序
open class MyApplication : Application() {
val appComponent: AppComponent by lazy {
initializeComponent()
}
open fun initializeComponent(): AppComponent {
return DaggerAppComponent.factory().create(applicationContext)
}
}
Step 6
测试应用
class TestApplication : MyApplication() {
override fun initializeComponent(): AppComponent {
return DaggerTestAppComponent.create()
}
}
完成这些步骤后,我运行了一个测试,以便 Dagger 可以生成 DaggerTestAppComponent,但它不会生成 DaggerTestAppComponent.create(),从而在代码中创建未解析的引用。
DaggerTestAppComponent
@SuppressWarnings({
"unchecked",
"rawtypes"
})
public final class DaggerTestAppComponent implements TestAppComponent {
private Provider<MyRepository> myRepositoryProvider;
private Provider<Context> contextProvider;
private Provider<MyDatabase> provideDatabaseProvider;
private Provider<ItemDao> provideDaoProvider;
private Provider<RoomRepository> roomRepositoryProvider;
private Provider<CoroutineDispatcher> providesIoDispatcherProvider;
private Provider<MainViewModel> mainViewModelProvider;
private DaggerTestAppComponent(DispatchersModule dispatchersModuleParam, Context contextParam) {
initialize(dispatchersModuleParam, contextParam);
}
public static TestAppComponent.Factory factory() {
return new Factory();
}
private MyAdapter myAdapter() {
return new MyAdapter(mainViewModelProvider.get());
}
@SuppressWarnings("unchecked")
private void initialize(final DispatchersModule dispatchersModuleParam,
final Context contextParam) {
this.myRepositoryProvider = MyRepository_Factory.create((Provider) FakeSaveData_Factory.create());
this.contextProvider = InstanceFactory.create(contextParam);
this.provideDatabaseProvider = DoubleCheck.provider(RoomModule_Companion_ProvideDatabaseFactory.create(contextProvider));
this.provideDaoProvider = DoubleCheck.provider(RoomModule_Companion_ProvideDaoFactory.create(provideDatabaseProvider));
this.roomRepositoryProvider = RoomRepository_Factory.create(provideDaoProvider);
this.providesIoDispatcherProvider = DispatchersModule_ProvidesIoDispatcherFactory.create(dispatchersModuleParam);
this.mainViewModelProvider = DoubleCheck.provider(MainViewModel_Factory.create(myRepositoryProvider, roomRepositoryProvider, providesIoDispatcherProvider));
}
@Override
public void inject(MainActivity arg0) {
injectMainActivity(arg0);
}
@Override
public void inject(ListFragment arg0) {
injectListFragment(arg0);
}
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectViewModel(instance, mainViewModelProvider.get());
return instance;
}
private ListFragment injectListFragment(ListFragment instance) {
ListFragment_MembersInjector.injectRvAdapter(instance, myAdapter());
return instance;
}
private static final class Factory implements TestAppComponent.Factory {
@Override
public TestAppComponent create(Context context) {
Preconditions.checkNotNull(context);
return new DaggerTestAppComponent(new DispatchersModule(), context);
}
}
}
如果我没有在应用程序中安装房间,Dagger 将生成DaggerTestAppComponent.create()。一旦设置房间 Dagger 停止生成DaggerTestAppComponent.create()。
Dagger 依赖项
def dagger_version = "2.33"
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
kapt "com.google.dagger:dagger-android-processor:$dagger_version"
kaptAndroidTest "com.google.dagger:dagger-compiler:$dagger_version"
构建输出
> Task :app:compileDebugAndroidTestKotlin FAILED
e: C:\Android\TestingEx\EndToEnd\app\src\androidTest\java\com\example\endtoend\TestApplication.kt: (14, 39): Unresolved reference: create
【问题讨论】:
-
在构建过程中是否有错误?
-
@Ruokki 未解决对
DaggerTestAppComponent.create()的引用。生成DaggerTestAppcomponeont时应该生成哪个。 -
是的,但在大多数情况下,当 DaggerXXXComponent 类没有出现时,您将在构建中看到错误日志,解释您的 dagger 组件有什么问题(循环参考/未提供依赖项/等)
-
@Ruokki,我已将构建输出包含在问题中。
标签: android android-espresso dagger-2