【发布时间】:2015-04-10 02:03:39
【问题描述】:
我正在为我的一些模型使用 ActiveAndroid,我想开始对我的工作进行单元测试。不幸的是,我遇到了很多错误,即无法使用正确的上下文初始化 ActiveAndroid。
ActiveAndroid 被初始化:
ActiveAndroid.initialize(context)
我尝试通过以下方式初始化上下文:
-
有一个扩展应用程序的存根类,并使用它来初始化数据库。
private class TestApp extends com.activeandroid.app.Application{ @Override public void onCreate() { super.onCreate(); initialiseDB(getDatabaseName()); } protected String getDatabaseName() { return "sad"; } private void initialiseDB(String dbName) { ActiveAndroid.initialize(this); } }
这失败了,因为 .getPackageName() 和 .getApplicationContext() 的类返回 null,这两者都由初始化在内部使用。
我也尝试过使用 ShadowContextWrapper,但我可能用错了。这是我的做法:
ShadowContextWrapper shadowContextWrapper = new ShadowContextWrapper();
shadowContextWrapper.setApplicationName("appName");
shadowContextWrapper.setPackageName("package");
Context context = shadowContextWrapper.getApplicationContext();
此方法在 ShadowContextWrapper.java:52 处出现 NPE 失败 Robolectric 的哪个部分。线路本身:
Context applicationContext = this.realContextWrapper.getBaseContext().getApplicationContext();
我正在使用 AS 1.2、robolectric3.0 和 activeandroid 3.1。
这是我正在运行的测试示例。
@RunWith(CustomRobolectricTestRunner.class)
public class ItemTest {
public void setUp(){
}
@Test
public void checkJUnitWork() {
assertThat(true, is(true));
}
@Test
public void testSave(){
Item item = new Item("name", "units", 5.0, 4.5, 10.0);
assertThat(item.getName(),is("name"));
}
public void tearDown(){
}
}
我的自定义Runner如下:
public class CustomRobolectricTestRunner extends RobolectricTestRunner {
public CustomRobolectricTestRunner(Class<?> testClass)
throws InitializationError {
super(testClass);
String buildVariant = (BuildConfig.FLAVOR.isEmpty()
? "" : BuildConfig.FLAVOR+ "/") + BuildConfig.BUILD_TYPE;
String intermediatesPath = BuildConfig.class.getResource("")
.toString().replace("file:", "");
intermediatesPath = intermediatesPath
.substring(0, intermediatesPath.indexOf("/classes"));
System.setProperty("android.package",
BuildConfig.APPLICATION_ID);
System.setProperty("android.manifest",
intermediatesPath + "/manifests/full/"
+ buildVariant + "/AndroidManifest.xml");
System.setProperty("android.resources",
intermediatesPath + "/res/" + buildVariant);
System.setProperty("android.assets",
intermediatesPath + "/assets/" + buildVariant);
ShadowContextWrapper shadowContextWrapper = new ShadowContextWrapper();
shadowContextWrapper.setApplicationName("appName");
shadowContextWrapper.setPackageName("package");
Context context = shadowContextWrapper.getApplicationContext();
ActiveAndroid.initialize(context);
}
}
【问题讨论】:
-
因为它是单元测试,所以我会从测试中删除 ActiveRecord
-
您能否也添加您的测试代码和您用于测试的清单文件?我偷偷怀疑 Robolectric 创建应用程序的方式可能有些奇怪
-
@EugenMartynov 嘿。我想过这样做。但是我的模型上有一些业务逻辑,我想对其进行测试。另外,我想做一些数据库工作,比如安装夹具数据并对其进行测试。因此,我真的需要这个来工作。
-
@abest 我不确定你指的是什么清单。我已经包含了我的测试运行器类,以及一个示例测试。
-
我应该更清楚地说,我将删除对数据库的依赖,以消除与数据库无关的所有测试。我鼓励你阅读这篇文章medium.com/@artem_zin/…
标签: android unit-testing robolectric android-context activeandroid