I have an app that make some calls to a REST API. I am using Retrofit to implement the API and I am using Roboguice to inject my REST service where needed.
I am trying to write up a test suite using espresso. I want to use a custom injection module so I can mock responses for Retrofit using Mockito.
How can I change my test suite to use a custom injection module from Roboguice keeping espresso.
PS: I've seen how to do this with Roboelectric, but I am not using Roboelectric right now.
I stumbled upon the same problem and I couldn't find an easy solution for this online. After a day of tries and fails, I finally found a solution which works for me.
You need to declare a custom ActivityTestRule class to override the Application Injector before the activity is launched. Here is an example :
@RunWith(AndroidJUnit4.class)
public class LoginActivityTest {
protected final Api mApi = mock(Api.class);
// declare the other mocks you want here
protected final AbstractModule mTestModule = new MyTestModule();
@Rule
public ActivityTestRule<LoginActivity> mActivityRule = new RoboGuiceActivityTestRule<>(LoginActivity.class);
private class RoboGuiceActivityTestRule<T extends Activity> extends ActivityTestRule<T> {
public RoboGuiceActivityTestRule(Class<T> activityClass) {
super(activityClass);
}
@Override
protected void beforeActivityLaunched() {
RoboGuice.overrideApplicationInjector((Application) InstrumentationRegistry.getTargetContext().getApplicationContext(), mTestModule);
}
}
private class MyTestModule extends AbstractModule {
@Override
protected void configure() {
bind(Api.class).toInstance(mApi);
// bind the other mocks here
}
}
@Test
public void checkEmptyFormDoNotPerformLogin() throws Exception {
onView(withId(R.id.etLogin)).perform(clearText());
onView(withId(R.id.etPassword)).perform(clearText());
onView(withId(R.id.btLogin)).perform(click());
verify(mApi, times(0)).login("", "");
}
// ...
}
Of course, you can extract the class and pass the module to the constructor for a cleaner code.