Intereting Posts

Robolectric: выполнение нескольких тестов не выполняется

Я пытаюсь запустить несколько тестов с помощью Robolectric 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) 

Уже пробовал некоторые решения, такие как реселлинг singleton со следующим кодом, который заканчивается 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(); } } 

Изменить: исправлено его, удалив sendUpdateEvent () из AppInstanceUpdater D360Sdk.

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

Это старый вопрос, но, возможно, это решение может помочь кому-то, поскольку я столкнулся с подобной проблемой (точно такая же ошибка).

Проблема в том, что при запуске нескольких тестовых примеров, которые несколько раз обращаются к базе данных, первый тестовый пример открывает соединение с базой данных и не закрывает его. Когда второй тестовый пример пытается открыть соединение с базой данных снова, он терпит неудачу.

Я прочитал некоторые решения и, наконец, понял, что проблема связана с открытием базы данных несколько раз. Чтобы успешно выполнить тесты, выполните следующую конфигурацию в файле 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(); } 

Вышеупомянутые две функции, аннотированные «@Before» и «@After», выполняются до и после каждого тестового примера. Таким образом, для каждого тестового примера мы должны закрыть соединение с базой данных.

Это и эти ссылки помогли.

Прокомментируйте, если что-то не так в решении или если мое понимание этой ошибки неверно.