我正在尝试使用 Roitelectric 3.0 + Gradle 使用 SQLite(OpenHelper)作为数据库运行多个测试。 运行每个单独的测试工作正常,但启动整个测试套件总是在第二次测试中导致RuntimeException。
这是我的测试假人,但不起作用。
@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结束,因此无效。
@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()来修复它。
AppInstanceUpdater updater = D360Sdk.getCrmAppInstanceUpdater();
updater.setCustomId(Util.installId());
// updater.sendUpdateEvent();
答案 0 :(得分:11)
这是一个老问题,但也许这个解决方案可以帮助某人,因为我遇到了类似的问题(完全相同的错误)。
问题是,在运行多次访问数据库的多个测试用例时,第一个测试用例打开与数据库的连接,但不关闭它。当第二个测试用例再次尝试打开数据库连接时,它会失败。
我阅读了一些解决方案,最后发现问题在于多次打开数据库。因此,要成功运行测试,请在TestCase.java
文件(您编写测试用例的位置)中执行以下配置:
@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();
}
以上两个用&#34; @ Before&#34;注释的函数。 &&#34; @ After&#34;在每个测试用例之前和之后运行。因此,对于每个测试用例之后,我们应该关闭数据库连接。
请注意解决方案中是否有错误,或者我对此错误的理解是错误的。