我尝试为我的android项目设置测试环境。基本的Robolectric设置完成。我使用了这个不错的tutorial。如果我在Manifest.xml中注释掉SugarORM,那么所有测试都可以。但如果我想将它与SugarORM一起使用,我总是会收到此错误:
java.lang.NullPointerException at dalvik.system.DexFile $ DFEnum.hasMoreElements(DexFile.java:239)at at com.orm.SugarDb.getDomainClasses(SugarDb.java:37)at com.orm.SugarDb.createDatabase(SugarDb.java:104)at com.orm.SugarDb.onCreate(SugarDb.java:100)at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252) 在 android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164) 在com.orm.Database.getDB(Database.java:18)at com.orm.SugarApp.onTerminate(SugarApp.java:16)at org.robolectric.internal.ParallelUniverse.tearDownApplication(ParallelUniverse.java:133) 在 org.robolectric.RobolectricTestRunner $ 2.evaluate(RobolectricTestRunner.java:246) 在org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)at at org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71)at at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at at org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58)at at org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268)at at org.robolectric.RobolectricTestRunner $ 1.evaluate(RobolectricTestRunner.java:158) 在org.junit.runners.ParentRunner.run(ParentRunner.java:363)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
每个人都有同样的问题吗?
修改
也许是这样,因为Robolectric在测试后关机并且还没有完成。我的TestClass
@RunWith(RobolectricTestRunner.class)
@Config(manifest="./src/main/AndroidManifest.xml",emulateSdk=18)
public class MyActivityTest{
private ActivityController<OnLogActivity> controller = Robolectric.buildActivity(OnLogActivity.class).create().setup();
@Test
public void clickingLogin_shouldStartLoginActivity() {
OnLogActivity activity = controller.get();
assertTrue(activity.findViewById(R.id.login) instanceof Button);
}
}
编辑2.0:
Robolectric可以找到android:name=com.orm.SugarApp
您必须使用相同的com.orm包创建一个测试文件夹,并添加一个名为TestSugarApp的测试类。之后你可以测试所有的东西。
package com.orm;
...
@RunWith(RobolectricTestRunner.class)
@Config(manifest="./src/main/AndroidManifest.xml",emulateSdk=18)
public class TestSugarApp extends Application
implements TestLifecycleApplication {
private ActivityController<OnLogActivity> controller;
@Test
public void startEverTestSugarAppAsFirst() {
}
@Override
public void beforeTest(Method method) {
Log.v("test", "beforeTest");
}
@Override
public void prepareTest(Object test) {
Log.v("test", "prepareTest");
}
@Override
public void afterTest(Method method) {
Log.v("test", "afterTest");
}
}
答案 0 :(得分:5)
好的,接下来尝试。将下一课添加到测试代码中:
public class TestSugarApp
extends SugarApp
{
@Override
public void onCreate() {}
@Override
public void onTerminate() {}
}
名为Test的类将由Robolectric加载和使用,您可以覆盖一些与测试无关的内容。我试图阻止在SugarApp
和onCreate
(https://github.com/satyan/sugar/blob/master/library/src/com/orm/SugarApp.java)onTerminate
执行代码。
答案 1 :(得分:1)
我使用此代码解决了这个问题:
测试代码中的Application类(与Eugen的答案相反):
public class TestApp extends App {
/** Prevents onCreate() and onTerminate() to call their super (in which {@link com.orm.SugarApp} is initialized) */
@Override
protected boolean callSuper() {
return false;
}
}
我自己的Application类(扩展SugarApp):
public class App extends com.orm.SugarApp {
private static Context context;
public static Context getContext() {
return context;
}
@Override
public void onCreate() {
if (callSuper()) {
super.onCreate();
}
// My own code is always executed, also during unittests
context = getApplicationContext();
}
@Override
public void onTerminate() {
if (callSuper()) {
super.onTerminate();
}
}
protected boolean callSuper() {
return true; // Super is executed by default
}
}
我同意它看起来不是很漂亮(任何建议让它变得更好?),但它对我来说非常合适!
PS。我在我的清单中声明了我的应用程序类:
<application
android:name=".App"