Dagger 和 Room,不创建 DaggerTestAppComoponent.create()

Dagger and Room, not creating DaggerTestAppComoponent.create()

我正在尝试 运行 在使用 Dagger 和 Room 的应用程序上进行端到端测试,当我 运行 应用程序 Dagger 无法生成 DaggerTestAppComponent.create().

我一直在关注 Dagger codelab 将 Dagger 实施到测试中。

这是 link Github 上的存储库。 https://github.com/Shawn-Nichol/EndToEnd

Step 1. Custom Test Runner 使用自定义测试 运行ner 以使用不同的应用程序 class.

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. 自定义测试 运行ner 在应用构建 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().

匕首依赖项

    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

您的 Dagger AndroidTest 设置似乎有两个问题。

TestApplication 正在调用一个不存在的函数。

class TestApplication : MyApplication() {

override fun initializeComponent(): AppComponent {
    return DaggerTestAppComponent.create()
} }

你想要returnDaggerTestAppComponent.factory().create(),你可以在生成的DaggerTestAppComponent文件的底部看到它。

return DaggerTestAppComponent.factory().create(this)

第二名 在 TestAppComponent 中,create() 函数 return 是匕首 AppComponent 图,您需要对其进行更改,因此它 return 是 TestAppComponent 图。

@Singleton
@Component(modules = [
    TestSaveDataStorageModule::class,
    RoomModule::class
])
interface TestAppComponent : AppComponent {


    @Component.Factory
    interface Factory {
        fun create(@BindsInstance context: Context): TestAppComponent
    }
}