【发布时间】:2014-08-14 22:03:52
【问题描述】:
我正在尝试使用 Dagger 编写一个 Android 应用程序。为了遵循 TDD 方法,我开始为我的第一个活动编写测试。对于编写测试,我使用的是 Robolectric,并且我正在尝试使用 Mockito 使其在不同的场景中工作。
短篇小说:
我有一个想要使用 robolectric 测试的 android 活动。这个活动有一些通过 Dagger 提供的依赖项。我设法通过重写 Application 类并提供实用程序类的模拟来完成这项工作。我现在需要的是能够在同一个单元测试文件中更改实用程序类的行为(使用 Mockito)来测试不同的场景。
长篇大论:
开发测试环境:Android Studio 0.8.6、gradle 0.12、dagger 1.2.2、robolectric 2.3
基础应用类:
public class MyApplication extends DaggerApplication
{
@Override
protected List<Object> getAppModules() {
List<Object> modules = new ArrayList<Object>();
modules.add(new AppModule(this));
return modules;
}
}
DaggerApplication 类:
public abstract class DaggerApplication extends Application {
private ObjectGraph mObjectGraph;
@Override
public void onCreate() {
super.onCreate();
AndroidAppModule sharedAppModule = new AndroidAppModule(this);
List<Object> modules = new ArrayList<Object>();
modules.add(sharedAppModule);
modules.addAll(getAppModules());
mObjectGraph = ObjectGraph.create(modules.toArray());
}
protected abstract List<Object> getAppModules();
@Override
public void inject(Object object) {
mObjectGraph.inject(object);
}
@Override
public ObjectGraph getObjectGraph() {
return mObjectGraph;
}
}
测试应用:
public class TestMyApplication extends MyApplication{
@Override
protected List<Object> getAppModules() {
List<Object> modules = super.getAppModules();
modules.add(new GeneralUtilsModuleNoInternetConnection());
return modules;
}
public static <T> void injectMocks(T object) {
CursuriDeSchimbApplication app = (TestCursuriDeSchimbApplication) Robolectric.application;
app.inject(object);
}
}
AppModule 类:
@Module(
injects = {
SplashScreenActivity.class
},
includes = AndroidAppModule.class
)
public class AppModule {
private Context app;
public AppModule()
{
}
public AppModule(Context app) {
this.app = app;
}
@Provides
@Singleton
GeneralUtils provideGeneralUtils() {
return new GeneralUtils();
}
}
测试模块类:
@Module(
includes = AppModule.class,
injects = {SplashScreenActivityTest.class,
SplashScreenActivity.class},
overrides = true
)
public class GeneralUtilsModuleNoInternetConnection
{
public GeneralUtilsModuleNoInternetConnection() {
}
@Provides
@Singleton
GeneralUtils provideGeneralUtils() {
GeneralUtils mockGeneralUtils = Mockito.mock(GeneralUtils.class);
when(mockGeneralUtils.isInternetConnection()).thenReturn(false);
return mockGeneralUtils;
}
}
测试类:
@RunWith(RobolectricTestRunner.class)
public class SplashScreenActivityTest
{
SplashScreenActivity activity;
@Before
public void setUp()
{
activity = Robolectric.buildActivity(SplashScreenActivity.class).create().get();
}
@Test
public void testOnCreate_whenNoInternetConnection()
{
<!-- Here I want GeneralUtils to return false when asking for internet connection -->
}
@Test
public void testOnCreate_whenThereIsInternetConnection()
{
<!-- Here I want GeneralUtils to return true when asking for internet connection -->
}
}
如果您需要更多信息,请务必询问。 总结一下:我想知道如何在同一个测试类中针对不同的测试场景使用不同的测试匕首模块。
谢谢。
【问题讨论】:
-
测试类中正在初始化的模块在哪里?
-
它在 TestMyApplication 类中初始化,该类由 robolectric 测试而不是 MyApplication 使用。具体代码为getAppModules()方法中的
modules.add(new GeneralUtilsModuleNoInternetConnection());。
标签: android unit-testing robolectric dagger