问题
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);
}
}
Exception
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)
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();
}
}
Edit: fixed it by removing sendUpdateEvent() of D360Sdk's AppInstanceUpdater.
AppInstanceUpdater updater = D360Sdk.getCrmAppInstanceUpdater();
updater.setCustomId(Util.installId());
// updater.sendUpdateEvent();
回答1:
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.
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();
}
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 and this links helped.
Please comment if there is something wrong in the solution or if my understanding of this error is wrong.
来源:https://stackoverflow.com/questions/34742685/robolectric-running-multiple-tests-fails