使用AndroidInjector和Subcomponents使得无法将对象范围内的活动注入到Espresso的Test类中。
以前使用应用程序级组件和活动组件,只要您创建继承活动组件的测试组件,就可以为非活动的测试类调用inject()。
示例:
活动组件
@ActivityScope
@Component(
dependencies = ApplicationComponent.class,
modules = {
NowPlayingActivityModule.class
})
public interface NowPlayingActivityComponent {
void inject(NowPlayingActivity activity);
}
测试类组件
@ActivityScope
@Component(
dependencies = TestApplicationComponent.class,
modules = {
TestNowPlayingActivityModule.class,
ActivityModule.class
})
public interface TestNowPlayingActivityComponent extends NowPlayingActivityComponent {
void inject(NowPlayingActivityTest nowPlayingActivityTest);
}
测试模块
@Module
public class TestNowPlayingActivityModule {
private NowPlayingActivityModule nowPlayingActivityModule;
public TestNowPlayingActivityModule(NowPlayingActivityModule nowPlayingActivityModule) {
this.nowPlayingActivityModule = nowPlayingActivityModule;
}
@Provides
@ActivityScope
public ServiceGateway providesServiceGateway(ServiceApi serviceApi) {
return nowPlayingActivityModule.providesServiceGateway(serviceApi);
}
@Provides
@ActivityScope
public NowPlayingPresenter providesNowPlayingPresenter(NowPlayingInteractor nowPlayingInteractor) {
//In order to make sure espresso idles the view checks, we put the IdlingResource on the presenter.
return Mockito.spy(new NowPlayingPresenterImpl_IdlingResource(nowPlayingActivityModule.getNowPlayingViewModel(),
nowPlayingInteractor));
}
}
在测试类中
TestNowPlayingActivityComponent mockNowPlayingActivityComponent = DaggerTestNowPlayingActivityComponent.builder()
.testApplicationComponent((TestApplicationComponent) mvpExampleApplication.getComponent())
.testNowPlayingActivityModule(new TestNowPlayingActivityModule(nowPlayingActivityModule))
.build();
mockNowPlayingActivityComponent.inject((NowPlayingActivity) activity);
mockNowPlayingActivityComponent.inject(NowPlayingActivityTest.this);
人们如何访问自动生成的活动模块并在espresso UI Test中使用它们?我希望能够访问像“ServiceGateway”这样的对象。上面的“NowPlayingPresenter”并在测试中使用它们。模拟,间谍或空闲资源。上面示例中的空闲资源是“NowPlayingPresenter”具体实现,我在每次单独测试时都会传递给espresso。
答案 0 :(得分:0)
前几天我设法使用自定义测试运行器进行了一些hacky方法来解决这个问题。首先是拥有TestRunner for faking the Android Application。现在,您可以简单地扩展主app类并覆盖onCreate()
,注入一个component built especially for testing,返回模拟实例而不是真实实例。
答案 1 :(得分:0)
我发现自己处于类似情况。这是我的问题Espresso testing with Dagger 2 and custom scopes。使用Espresso进行测试时注入嘲笑非常棘手。
mcassiano建议的方法是解决这个问题的第一个想法。但是,我没有采用这种方法,因为必须创建代码开销。我很想知道mcassiano创建的Espresso测试是什么样的。我假设您为Activity注册了一个ActivityTestRule,以便注入模拟。
在使用Dagger 2的理想场景中,我想避免以下情况:
后者我认为是一种代码味道,因为如果我们最终遇到上述任何一种情况,我们将拥有一个巨大的App组件和模块,它们与每个应用程序功能紧密结合。
应该发生的是让每个功能都负责注入它自己的依赖项。
关于寻找注入模拟的解决方案,我有以下想法,我没有实现,因为我不想将测试与生产代码混合。但是,如果你们分享你的想法,我们将不胜感激。