I’m trying to test an Activity with Mockito & Dagger. I have been able to inject dependencies to Activity in my application but when testing the Activity, I have not been able to inject mock to the Activity. Should I inject Activity to test or let getActivity() create it?
public class MainActivityTest extends
ActivityInstrumentationTestCase2<MainActivity> {
@Inject Engine engineMock;
private MainActivity mActivity;
private Button mLogoutBtn;
public MainActivityTest() {
super(MainActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
// Inject engineMock to test
ObjectGraph.create(new TestModule()).inject(this);
}
@Override
protected void tearDown() {
if (mActivity != null)
mActivity.finish();
}
@Module(
includes = MainModule.class,
entryPoints = MainActivityTest.class,
overrides = true
)
static class TestModule {
@Provides
@Singleton
Engine provideEngine() {
return mock(Engine.class);
}
}
@UiThreadTest
public void testLogoutButton() {
when(engineMock.isLoggedIn()).thenReturn(true);
mActivity = getActivity();
mLogoutBtn = (Button) mActivity.findViewById(R.id.logoutButton);
// how to inject engineMock to Activity under test?
ObjectGraph.create(new TestModule()).inject(this.mActivity);
assertTrue(mLogoutBtn.isEnabled() == true);
}
}
I use Mockito and Dagger for functional testing. The key concept is that your test class inherits from ActivityUnitTestCase, instead of ActivityInstrumentationTestCase2; the latter super-class call onStart() life-cycle method of Activity blocking you for inject your test doubles dependencies, but with first super-class you can handle the life-cycle more fine-grained.
You can see my working examples using dagger-1.0.0 and mockito for test Activities and Fragments in:
https://github.com/IIIRepublica/android-civicrm-test
The project under test is in:
https://github.com/IIIRepublica/android-civicrm
Hope this helps you
I have put everything together and made demo app that shows how to test with dagger: https://github.com/vovkab/dagger-unit-test
Here is my pervious answer with more details:
https://stackoverflow.com/a/24393265/369348
I did some more experimenting and found out that Dagger is not able to create activity correctly when it is injected to test. In the new version of test, testDoSomethingCalledOnEngine passes but onCreate is not called on the MainActivity. The second test, testDoSomethingUI fails and there are actually two instances of MainActivity, onCreate gets called to the other instance (created by ActivityInstrumentationTestCase2 I quess) but not to the other. Maybe the developers at Square only thought about testing Activites with Robolectric instead of Android instrumentation test?
}