Android 带有 Dagger 2 的纯 Junit

Android plain Junit with Dagger 2

我曾经在 MVP 工作,我通常使用普通的 Junit(不是 Instrumentation!)测试我的 Presenter,因为 Presenter 只有业务逻辑,没有任何对 Android 内部的引用。

现在切换到 Dagger 2 后,我了解到我在为我的应用程序组件设置 "TestModule" 时遇到了问题。

  1. 创建组件在测试中不起作用 class(可能是因为 "apt" 没有 运行)
  2. 未找到任何将 Dagger 与标准 Junit 测试结合使用的示例。我发现的每个示例都只依赖于 Instrumentation 测试或 Roboelectric(基本上模拟 Activities 和其他 Android 相关的东西),但这对我来说只是一个 UI 测试,我不需要那个。

为了清楚起见,我说的是位于 app->src->test 文件夹而不是 app->src->androidTest 的测试!

那我是不是做错了什么?还是遗漏了什么?谁能解释或举例说明如何在正常单元测试中使用 Dagger 2?

你不需要任何匕首来测试你的演讲者。 Dagger 的工作是填充 类 的依赖项(依赖注入)。

例如你有这个演示者:

public class MyPresenter {

    Database database;
    ApiService apiService;

    @Inject
    public MyPresenter(final Database database, final ApiService apiService) {
        this.database = database;
        this.apiService = apiService;
    }
}

Dagger 将为您的 Presenter 提供 databaseapiService 对象,供您的 Presenter 使用。当 运行 实际应用程序(不是测试)时,这些将是具有真实功能的真实对象。

当测试presenter时,你只想测试presenter,其他的都应该被模拟。

因此,当您在 PresenterTest 中创建演示者时,您会使用 databaseapiService 的模拟版本创建它。

然后您可以通过

测试演示者如何与这些对象交互

一个。模拟对象的行为,例如

when(database.getSomething()).thenReturn(something)

b。验证您的演示者对这些对象做了您希望它做的事情,例如

verify(database).saveSomething()

(伪代码)

模拟的标准方法是 Mockito。

我不确定我的解决方案是否适合您,但我认为没有理由不适合您。 首先我创建了 testInjectionComponent

@Singleton
@Component(modules = {MockNetworkModule.class})
public interface MockInjectionComponent extends InjectionComponent {
void inject(DaggerUnitTest daggerUnitTest);
}

然后我的单元测试我在之前的方法中添加了注入。像这样:

@Before
public void setUp() throws Exception {
    MockInjectionComponent mockInjectionComponent = DaggerMockInjectionComponent
            .builder()
            .mockNetworkModule(new MockNetworkModule())
            .build();
    mockInjectionComponent.inject(this);
}

然后我只是注释我的注入对象。

编辑: 不要忘记在 app.gradle 文件中添加 testApt "com.google.dagger:dagger-compiler:$daggerVersion"

您可以通过两种方式用假模块替换真实模块:在编译时使用 google architecture samples 推荐的风格或在运行时通过创建一个抽象方法在生产代码中注入真实的东西来完成测试代码中的假依赖。在第二种情况下,您的测试必须子 class 您想要模拟的 class 并从头开始构建组件

如已接受的答案所述。不要忘记添加:

对于Java

Android 测试

androidTestAnnotationProcessor 'com.google.dagger:dagger-compiler:$dagger_version'

JUnit 测试

testAnnotationProcessor 'com.google.dagger:dagger-compiler:$dagger_version'

对于 Kotlin

Android 测试

kaptAndroidTest 'com.google.dagger:dagger-compiler:$dagger_version'

JUnit 测试

kaptTest 'com.google.dagger:dagger-compiler:$dagger_version'