3

我试图为我的 android 项目设置一个测试环境。基本的 Robolectric 设置已完成。我使用了这个不错的教程。如果我在 Manifest.xml 中注释掉 SugarORM,则所有测试都可以正常工作。但是如果我想将它与 SugarORM 一起使用,我总是会收到此错误:

java.lang.NullPointerException at dalvik.system.DexFile$DFEnum.hasMoreElements(DexFile.java:239) at com.orm.SugarDb.getDomainClasses(SugarDb.java:37) at com.orm.SugarDb.createDatabase(SugarDb.java: 104) 在 com.orm.SugarDb.onCreate(SugarDb.java:100) 在 android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252) 在 android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164) ) 在 com.orm.Database.getDB(Database.java:18) 在 com.orm.SugarApp.onTerminate(SugarApp.java:16) 在 org.robolectric.internal.ParallelUniverse.tearDownApplication(ParallelUniverse.java:133) 在 org .robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:246) 在 org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 在 org.junit.runners.BlockJUnit4ClassRunner。runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners。 ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit .runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org. junit.runner.JUnitCore.run(JUnitCore.java:137) 在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)57) 在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 在 org.junit.runners.ParentRunner.runChildren(ParentRunner .java:288) 在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 在 org.robolectric.RobolectricTestRunner$1.evaluate (RobolectricTestRunner.java:158) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:363) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:137) 在 com.intellij.rt.execution。应用程序.AppMain.main(AppMain.java:134)57) 在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 在 org.junit.runners.ParentRunner.runChildren(ParentRunner .java:288) 在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 在 org.robolectric.RobolectricTestRunner$1.evaluate (RobolectricTestRunner.java:158) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:363) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:137) 在 com.intellij.rt.execution。应用程序.AppMain.main(AppMain.java:134)ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158) at org.junit。 runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158) at org.junit。 runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

每个人都有同样的问题吗?

编辑

可能是这样,因为测试后 Robolectric 关机,sugarorm 仍未完成。我的测试班

@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");
    }
}
4

2 回答 2

5

好的,接下来试试。将下一个类添加到您的测试代码中:

public class TestSugarApp
    extends SugarApp
{
    @Override
    public void onCreate() {}

    @Override
    public void onTerminate() {}
}

Robolectric 将加载和使用名为 Test 的类,您可以覆盖一些与测试无关的内容。我试图阻止从SugarApponCreateonTerminatehttps://github.com/satyan/sugar/blob/master/library/src/com/orm/SugarApp.java 执行代码。

于 2015-01-18T18:03:20.653 回答
1

@Eugen Martynov 的回答完美(非常感谢!)。但是,当您自己扩展了 android.app.Application(它又扩展了 SugarApp)时,您也将排除您自己的代码。

我已经使用以下代码解决了这个问题:

测试代码中的 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;
    }
}

我自己的应用程序类(扩展 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
    }
}

我同意它看起来不是很漂亮(有什么建议可以让它变得更好吗?),但它对我来说非常有用!

附言。我在清单中声明了我的应用程序类,如下所示:

<application
    android:name=".App"
于 2017-06-07T19:53:36.953 回答