我想测试一个活动与Mockito &dagger。我已经能够在我的应用程序中注入对活动的依赖关系,但在测试活动时,我无法向活动注入模拟。我应该注入活动来测试还是让getActivity()创建它?
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);
}
}
我使用Mockito和Dagger进行功能测试。关键的概念是你的测试类继承自ActivityUnitTestCase,而不是ActivityInstrumentationTestCase2;后一个超类调用onStart()生命周期方法的Activity阻止你注入你的测试双精度依赖,但是有了第一个超类,你可以处理更细粒度的生命周期。
你可以看到我使用dagger-1.0.0和mockito测试活动和片段的工作示例:
https://github.com/IIIRepublica/android-civicrm-test正在测试的项目在:
https://github.com/IIIRepublica/android-civicrm希望这对你有帮助
我做了更多的实验,发现Dagger在注入测试时无法正确创建活动。在新版本的test中,testDoSomethingCalledOnEngine通过了,但在MainActivity上没有调用onCreate。第二个测试,testDoSomethingUI失败,实际上有MainActivity的两个实例,onCreate被调用到另一个实例(由ActivityInstrumentationTestCase2创建,我猜),但不是另一个。也许Square的开发者只考虑使用robolelectric而不是Android instrumentation测试来测试activities ?
public class MainActivityTest extends
ActivityInstrumentationTestCase2<MainActivity> {
@Inject Engine engineMock;
@Inject MainActivity mActivity;
public MainActivityTest() {
super(MainActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
// Inject engineMock to test & Activity under test
ObjectGraph.create(new TestModule()).inject(this);
}
@Module(
includes = MainModule.class,
entryPoints = MainActivityTest.class,
overrides = true
)
static class TestModule {
@Provides
@Singleton
Engine provideEngine() {
return mock(Engine.class);
}
}
public void testDoSomethingCalledOnEngine() {
when(engineMock.isLoggedIn()).thenReturn(true);
mActivity.onSomethingHappened();
verify(engineMock).doSomething();
}
@UiThreadTest
public void testDoSomethingUI() {
when(engineMock.isLoggedIn()).thenReturn(true);
mActivity.onSomethingHappened();
Button btn = (Button) mActivity.findViewById(R.id.logoutButton);
String btnText = btn.getText().toString();
assertTrue(btnText.equals("Log out"));
}
}
我已经把所有的东西放在一起,并制作了演示应用程序,显示如何使用dagger进行测试:https://github.com/vovkab/dagger-unit-test
以下是我之前的回答和更多细节:
https://stackoverflow.com/a/24393265/369348