Robolectric:运行多个测试失败 [英] Robolectric: running multiple tests fails

查看:60
本文介绍了Robolectric:运行多个测试失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 SQLite (OpenHelper) 作为数据库,使用 Robolectric 3.0 + Gradle 运行多个测试.运行每个单独的测试工作正常,但启动整个测试套件总是会在第二个测试中导致 RuntimeException.

I am trying to run multiple tests with Robolectric 3.0 + Gradle using SQLite (OpenHelper) as database. Running each single tests works fine, but starting the whole test suite always results in RuntimeException in the 2nd test.

这是我的测试假人,它不起作用.

This is my test dummy, which does not work.

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class Dummy {


    @Before
    public void setUp() throws Exception {
         // setup activity ...
    }

    @Test
    public void testA() throws Exception {
        Assert.assertTrue(true);
    }

    @Test
    public void testB() {
        Assert.assertTrue(true);
    }
}

异常

java.lang.RuntimeException: java.lang.IllegalStateException: Illegal connection pointer 1. Current pointers for thread Thread[pool-4-thread-1,5,main] []
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections.execute(ShadowSQLiteConnection.java:470)
    at org.robolectric.shadows.ShadowSQLiteConnection.nativeResetStatementAndClearBindings(ShadowSQLiteConnection.java:286)
    at android.database.sqlite.SQLiteConnection.nativeResetStatementAndClearBindings(SQLiteConnection.java)
    at android.database.sqlite.SQLiteConnection.releasePreparedStatement(SQLiteConnection.java:915)
    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:519)
    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
    at android.database.sqlite.SQLiteProgram.__constructor__(SQLiteProgram.java:58)
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java)
    at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java)
    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1469)
    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1341)
    at de.d360.android.sdk.v2.storage.db.datasource.AbstractDataSource.insert(AbstractDataSource.java:78)
    at de.d360.android.sdk.v2.storage.db.datasource.QueueMessageDataSource.create(QueueMessageDataSource.java:100)
    at de.d360.android.sdk.v2.net.Queue.addToHttpQueue(Queue.java:185)
    at de.d360.android.sdk.v2.D360Events.sendEvent(D360Events.java:1636)
    at de.d360.android.sdk.v2.D360Events.sendEvent(D360Events.java:1612)
    at de.d360.android.sdk.v2.D360Events.sendEvent(D360Events.java:1651)
    at de.d360.android.sdk.v2.D360Events.appInstanceUpdated(D360Events.java:359)
    at de.d360.android.sdk.v2.crm.AppInstanceUpdater.sendUpdateEvent(AppInstanceUpdater.java:27)
    at de.android.hotel.HotelApplication.onCreate(HotelApplication.java:281)
    at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:140)
    at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:433)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:240)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
    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:152)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.IllegalStateException: Illegal connection pointer 1. Current pointers for thread Thread[pool-4-thread-1,5,main] []
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections.getConnection(ShadowSQLiteConnection.java:333)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections.getStatement(ShadowSQLiteConnection.java:340)
    at org.robolectric.shadows.ShadowSQLiteConnection.stmt(ShadowSQLiteConnection.java:52)
    at org.robolectric.shadows.ShadowSQLiteConnection.access$000(ShadowSQLiteConnection.java:33)
    at org.robolectric.shadows.ShadowSQLiteConnection$16.call(ShadowSQLiteConnection.java:289)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections$6.call(ShadowSQLiteConnection.java:452)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections$6.call(ShadowSQLiteConnection.java:446)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalStateException: Illegal connection pointer 1. Current pointers for thread Thread[pool-4-thread-1,5,main] []
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:244)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
    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:152)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.RuntimeException: java.lang.IllegalStateException: Illegal connection pointer 1. Current pointers for thread Thread[pool-4-thread-1,5,main] []
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections.execute(ShadowSQLiteConnection.java:470)
    at org.robolectric.shadows.ShadowSQLiteConnection.nativeResetStatementAndClearBindings(ShadowSQLiteConnection.java:286)
    at android.database.sqlite.SQLiteConnection.nativeResetStatementAndClearBindings(SQLiteConnection.java)
    at android.database.sqlite.SQLiteConnection.releasePreparedStatement(SQLiteConnection.java:915)
    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:519)
    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
    at android.database.sqlite.SQLiteProgram.__constructor__(SQLiteProgram.java:58)
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java)
    at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java)
    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1469)
    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1341)
    at de.d360.android.sdk.v2.storage.db.datasource.AbstractDataSource.insert(AbstractDataSource.java:78)
    at de.d360.android.sdk.v2.storage.db.datasource.QueueMessageDataSource.create(QueueMessageDataSource.java:100)
    at de.d360.android.sdk.v2.net.Queue.addToHttpQueue(Queue.java:185)
    at de.d360.android.sdk.v2.D360Events.sendEvent(D360Events.java:1636)
    at de.d360.android.sdk.v2.D360Events.sendEvent(D360Events.java:1612)
    at de.d360.android.sdk.v2.D360Events.sendEvent(D360Events.java:1651)
    at de.d360.android.sdk.v2.D360Events.appInstanceUpdated(D360Events.java:359)
    at de.d360.android.sdk.v2.crm.AppInstanceUpdater.sendUpdateEvent(AppInstanceUpdater.java:27)
    at de.android.hotel.HotelApplication.onCreate(HotelApplication.java:281)
    at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:140)
    at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:433)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:240)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
    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:152)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    ... 1 more
Caused by: java.lang.IllegalStateException: Illegal connection pointer 1. Current pointers for thread Thread[pool-4-thread-1,5,main] []
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections.getConnection(ShadowSQLiteConnection.java:333)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections.getStatement(ShadowSQLiteConnection.java:340)
    at org.robolectric.shadows.ShadowSQLiteConnection.stmt(ShadowSQLiteConnection.java:52)
    at org.robolectric.shadows.ShadowSQLiteConnection.access$000(ShadowSQLiteConnection.java:33)
    at org.robolectric.shadows.ShadowSQLiteConnection$16.call(ShadowSQLiteConnection.java:289)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections$6.call(ShadowSQLiteConnection.java:452)
    at org.robolectric.shadows.ShadowSQLiteConnection$Connections$6.call(ShadowSQLiteConnection.java:446)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

已经尝试了一些解决方案,例如使用以下代码重置单例,以 FieldNotfoundException 或 NullPointerException 结尾,所以没有奏效.

Already tried some solutions like reseting singleton with the following code, which ends in FieldNotfoundException or NullPointerException, so did not work.

@After
public void finishComponentTesting() {
    // sInstance is the static variable name which holds the singleton instance
    resetSingleton(MySQLiteOpenHelper.class, "sInstance");
}

private void resetSingleton(Class clazz, String fieldName) {
    Field instance;
    try {
        instance = clazz.getDeclaredField(fieldName);
        instance.setAccessible(true);
        instance.set(null, null);
    } catch (Exception e) {
        throw new RuntimeException();
    }
}

通过删除 D360Sdk 的 AppInstanceUpdater 的 sendUpdateEvent() 修复它.

fixed it by removing sendUpdateEvent() of D360Sdk's AppInstanceUpdater.

AppInstanceUpdater updater = D360Sdk.getCrmAppInstanceUpdater();
updater.setCustomId(Util.installId());
// updater.sendUpdateEvent();

推荐答案

这是一个老问题,但也许这个解决方案可以帮助某人,因为我面临类似的问题(完全相同的错误).

It is an old question but maybe this solution can help someone as I was facing similar issue (exactly same error).

问题在于,在运行多个多次访问数据库的测试用例时,第一个测试用例打开了与数据库的连接,但并未关闭它.当第二个测试用例再次尝试打开数据库连接时,它失败了.

The issue is that while running multiple test cases which are accessing database multiple times, the first test case opens the connection to the database and does not close it. When second test case tries to open database connection again it fails.

我阅读了一些解决方案,最后发现问题在于多次打开数据库.因此,要成功运行测试,请在您的 TestCase.java 文件(您已在其中编写测试用例)中执行以下配置:

I read some solutions and finally figured out that the issue was with opening database multiple times. So to run tests successfully, do the following configuration in your TestCase.java file (where you have written your test cases):

@Before
public void setUp() throws Exception {
    //Get an instance of your implementation of SQLiteOpenHelper class.
    //Let's assume the class name is MySQLiteHelper which extends SQLiteOpenHelper and has a function called getInstance
    //which returns the instance of the SQLiteOpenHelper.
    //Store this instance in a global variable in your TestCase.java file.
    databaseHelper = MySQLiteHelper.getInstance();
}

@After
public void tearDown() throws Exception {
    //use the instance created in setUp() function to close the database
    databaseHelper.close();
}

上面两个用@Before"和@After"注释的函数在每个测试用例之前和之后运行.因此,对于每个测试用例,我们应该关闭数据库连接.

The above two functions annotated with "@Before" and "@After" run before and after every test case. So, for after each test case we should close the database connection.

这个this 链接有帮助.

如果解决方案有问题或者我对这个错误的理解有误,请发表评论.

Please comment if there is something wrong in the solution or if my understanding of this error is wrong.

这篇关于Robolectric:运行多个测试失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆