模拟依赖组件与DaggerMock

时间:2017-11-29 11:44:18

标签: android dagger-2 daggermock

我想为应用编写Espresso测试,所以我正在尝试DaggerMock 模拟一些外部依赖,如本地存储。

我的Dagger设置包含一个ApplicationComponent,包含3个模块(DatabaseModule,DataModule和ApplicationModule),对于我要测试的屏幕(Fragment)我还有另一个组件取决于ApplicationComponent

到目前为止我尝试的是:

@Rule public DaggerMockRule<ApplicationComponent> daggerRule =
        new DaggerMockRule<>(ApplicationComponent.class, new DatabaseModule(), new DataModule(application),
                new ApplicationModule(application)).set(
                component -> {
                    MyApplication app =
                            (MyApplication) InstrumentationRegistry.getInstrumentation()
                                    .getTargetContext()
                                    .getApplicationContext();
                    app.setComponent(component);
                });

@Rule
public final DaggerMockRule<FeedComponent> rule = new DaggerMockRule<>(
        FeedComponent.class, new FeedDataSourceModule(),
        new FeedDownloadImageUseCaseModule(), new FeedServiceModule(), new FeedPresenterModule(null))
        .addComponentDependency(ApplicationComponent.class, new DatabaseModule(), new DataModule(application), new ApplicationModule(application))
        .set(component -> localDataSource = component.localDataSource());

@Mock FeedDao feedDao;

@Mock NetworkUtils networkUtils;

@Mock FeedLocalDataSource localDataSource;

其中localDataSource实际上是我想要模拟的依赖项,它是FeedDataSourceModule中构建的:

@Module
public class FeedDataSourceModule {

@Provides
@FragmentScope
public FeedItemMapper providesFeedItemMapper() {
    return new FeedItemMapper();
}

@Provides
@FragmentScope
public FeedLocalDataSource providesFeedLocalDataSource(FeedDao feedDao, FeedRequestDetailsDao detailsDao, FeedItemMapper mapper) {
    return new FeedLocalDataSourceImpl(feedDao, detailsDao, mapper);
}

@Provides
@FragmentScope
public FeedRemoteDataSource providesFeedRemoteDataSource(FeedService feedService, FlagStateService flagStateService,
          @Named("Api-Token") String apiToken, @Named("Screen-Size") String screenSize,
                                                  @Named("Account-Id") String accountId) {
    return new FeedRemoteDataSourceImpl(feedService, flagStateService, apiToken, screenSize, accountId);
}

}

以及依赖于FeedComponent的{​​{1}}:

ApplicationComponent

根据我在上面发布的两个@FragmentScope @Component( dependencies = ApplicationComponent.class, modules = { FeedPresenterModule.class, FeedServiceModule.class, FeedDataSourceModule.class, FeedDownloadImageUseCaseModule.class}) public interface FeedComponent { @Named("Api-Token") String getApiToken(); @Named("Api-Key") String getApiKey(); FeedLocalDataSource localDataSource(); FeedRemoteDataSource remoteDataSource(); void inject(FeedFragment feedFragment); } ,我可以确认@Rules确实似乎已被正确模拟,因为我使用NetworkUtils返回Mockito.when()值并使用了我的代码中的断点我可以看到值始终为false:

false

when(networkUtils.isOnline()) .thenReturn(false); 并非如此,当我调用localDataSource时,虽然我已声明:{/ p>

localDataSource.getFeedSorted()

以防它有用,这就是我从 when(localDataSource.getFeedSorted()) .thenReturn(Flowable.just(feedList)); 注入依赖项的方法:

FeedComponent

1 个答案:

答案 0 :(得分:1)

为什么在测试中使用两个DaggerMock规则?我认为你可以使用像example这样的单一规则。