我的目标是编写测试测试,其中被测试的类是一个注入模拟演示器的Activity。我也希望主持人拥有与举办活动相同的生活。最后,还应该能够从测试类中引用注入活动的模拟演示者,以便可以设置,验证模拟等...作为测试的一部分。
项目设置:
我正在使用gradle flavor将项目分解为可用于我正在尝试编写的不同类型测试的源集。我有一个mockRepo风格,我有Dagger组件和模块,它创建了我所有依赖项的“真实”实例,除了我模拟的我的存储库。我有一个endToEnd风格,我注入每个依赖的真实实例。我试图添加的最后一种风格是mockPresenter风格,它创建了演示者的模拟实例,这样我就可以真正隔离我的视图,并确保当活动的生命周期方法运行时,在演示者上调用正确的方法。
mockRepo和endToEnd风格非常简单,因为在这两种情况下我都能够扩展应用程序类以进行测试,并且能够在应用程序类中交换出不同的dagger组件,这使得注入模拟存储库非常容易
mockPresenter风味给我带来了麻烦。问题是我无法在不添加类似
的方法的情况下将模拟演示者注入MainActivityDaggerMainComponent getMainComponent() {
return mDaggerMainComponent
}
到我的应用程序类。我不想这样做,因为看起来应用程序类根本不需要了解DaggerMainComponent,而这只是一种解决方法。
以下是MainActivity的注入代码目前的样子:
@Inject
MainContract.Presenter mMainPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMainComponent = DaggerMainComponent
.builder()
.appInjector(((MyApplication) getApplicationContext()).getAppComponent())
.mainModule(new MainModule())
.mainPresenterModule(new MainPresenterModule())
.build();
mMainComponent.inject(this);
mMainPresenter.setView(this);
}
我喜欢这样做的方法是在onCreate中我使用Dagger生成的类DaggerMainComponent来创建一个组件实例,它保证我将获得一个新的Component,它保证每次onCreate我都会得到一个新的presenter运行。此外,我可以在onCreate中获取对该组件的引用,并在onDestroy()中取消引用它。但是,似乎也不可能注入一个模拟的MainPresenter,因为我必须这样做的唯一机会是:
.mainPresenterModule(new MainPresenterModule())
MainPresenterModule只创建演示者的“真实”实例,如果我这样使用的话:
.mainPresenterModule(new MockPresenterModule())
然后就没有办法为该应用程序的生产版本使用“真实”版本的演示者。
我在这种情况下看到的变通办法似乎都涉及在应用程序类上有一个返回组件或模块的方法。在应用程序的生产版本中,应用程序类将返回依赖于提供实际实例的模块的组件,或者甚至可以仅提供模块本身。应用程序的测试版本将有一个测试应用程序,它将扩展生产应用程序类并覆盖某些方法,因此当测试应用程序运行时,它将返回组件的模拟版本,该模型版本将声明可提供模拟的模块或它将直接返回模拟模块。
我见过的其他解决方法在应用程序类中使用@ExposedForTesting注释,这似乎是我想要避免的。
让应用程序类公开getter方法,以便可以注入mock / real依赖项似乎是一种代码味道,因为我无法看到应用程序类应该知道应该注入MainActivity的依赖项的真正原因。此外,您似乎最终会在每个Activity或Fragment中使用一个getter方法,这会使应用程序类膨胀。
有没有办法将模拟注入到Activity中,以便应用程序类在提供正确的模块或组件方面没有那么大的作用?