Reputation: 1691
I want to write Espresso tests for an app so I'm trying DaggerMock
to
mock some external dependencies like local storage.
My Dagger
setup consists of an ApplicationComponent
with 3 modules (DatabaseModule, DataModule and ApplicationModule) and for the screen( a Fragment
) I want to test I have also another component which depends on ApplicationComponent
.
What I have tried so far is :
@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;
where localDataSource
is actually the dependency I want to mock and it's build in 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);
}
}
and also the FeedComponent
with the dependency on 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);
}
With the two @Rules
I posted above I can confirm that NetworkUtils
indeed seems to have been mocked correctly since I have used Mockito.when()
to return false
value and by using a breakpoint in my code I can see the value is always false :
when(networkUtils.isOnline())
.thenReturn(false);
But this is not true for localDataSource
which gives me null when I'm calling localDataSource.getFeedSorted()
although I have declared :
when(localDataSource.getFeedSorted())
.thenReturn(Flowable.just(feedList));
Just in case it helps, this is how I inject the dependencies from FeedComponent
:
DaggerFeedComponent.builder()
.applicationComponent(MyApplication.getApplicationComponent())
.feedPresenterModule(new FeedPresenterModule(this))
.build()
.inject(this);
Upvotes: 0
Views: 228
Reputation: 474
Why are you using two DaggerMock rules in a test? I think you can use a single rule like in this example.
Upvotes: 1