如何在所有测试中轻松地用假货替换生产 Hilt 模块

Ebo*_*ike 7 android dependency-injection dagger-hilt

我的 Android 生产是充满 Hilt 模块的代码,这些模块安装了各种生产实现:

@Module
@InstallIn(ApplicationComponent.class)
public abstract class TimeModule {...}
Run Code Online (Sandbox Code Playgroud)
@Module
@InstallIn(ApplicationComponent.class)
public abstract class DatabaseModule {...}
Run Code Online (Sandbox Code Playgroud)

在我所有的仪器测试中,我想用假货替换这些绑定。我的测试代码库包含绑定假实现的模块,但是让两个模块提供相同的类显然会导致编译时错误。

Hilt 文档建议使用@UninstallModule(),但这意味着我必须UninstallModule在每个测试中为每个生产模块添加。这似乎是错误的做法。

通常如何用假模块替换生产模块?有没有一种方法可以像 Guice 那样从另一个模块安装模块,这样我就可以@InstallIn从所有生产模块中删除,而只需使用一个ProductionModule安装所有单独模块的模块?这将使在测试中卸载一个模块变得更容易。

A. *_*rik 8

通常如何用假模块替换生产模块?

可能通常是如何完成的,就像文档中所说的那样UninstallModule注释所说的那样。但这里有一个替代方案,我喜欢使用它,使用构建风格:

我喜欢组织我的项目,所以有mock各种各样的live风格。我的应用程序模块中有 3 个文件夹:src/main/kotlinActivities、Fragments 等...,src/mock/kotlin其中包含我的假绑定,最后src/live/kotlin是我真正的生产绑定所在的位置。

app这是我级别的相关配置build.gradle.kts

android {
  productFlavors {
    flavorDimensions("environment")
    register("mock") {
      dimension = "environment"
    }

    register("dev") {
      dimension = "environment"
    }

    register("prod") {
      dimension = "environment"
    }

    sourceSets {
      getByName("mock").java.srcDir("src/mock/kotlin")
      getByName("dev").java.srcDir("src/live/kotlin")
      getByName("prod").java.srcDir("src/live/kotlin")
    }
  }
}

Run Code Online (Sandbox Code Playgroud)

项目结构概览

项目结构概览

现场直播内InteractorModule

@Module
@InstallIn(ApplicationComponent::class)
abstract class InteractorModule {
  @Binds
  abstract fun bindTodoInteractor(interactor: TodoInteractorImpl): TodoInteractor
}
Run Code Online (Sandbox Code Playgroud)

在 - 的里面FakeInteractorsModule

@Module
@InstallIn(ApplicationComponent::class)
abstract class InteractorModule {
  @Binds
  abstract fun bindTodoInteractor(interactor: TodoInteractorFake): TodoInteractor
}
Run Code Online (Sandbox Code Playgroud)

因此,现在您可以使用构建变体选项卡在接口的真实实现和模拟实现之间进行更改。因此,如果您想在仪器测试中使用假货,请在运行测试时使用模拟风格。

这种方法的一个优点是,通过更改构建变体,您可以在使用假货的仪器测试和使用实时实现之间进行切换。相反,您可以在实际应用程序中使用假实现,如果您只想使用模拟数据尝试应用程序,这可能会很好。

我希望这有助于至少促进一些想法,关于如何解决“一个接口的两种实现”的困境!