Robolectric: ejecutar múltiples pruebas falla

Estoy tratando de ejecutar múltiples pruebas con Robolectric 3.0 + Gradle utilizando SQLite (OpenHelper) como base de datos. Ejecutar cada una de las pruebas funciona bien, pero iniciar toda la suite de pruebas siempre da como resultado RuntimeException en la segunda prueba.

Este es mi maniquí de prueba, que no funciona.

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

Excepción

 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) 

Ya hemos probado algunas soluciones como reseting singleton con el código siguiente, que termina en FieldNotfoundException o NullPointerException, por lo que no funcionó.

 @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: arreglado eliminando sendUpdateEvent () del AppInstanceUpdater de D360Sdk.

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

Es una vieja pregunta, pero tal vez esta solución puede ayudar a alguien como yo estaba enfrentando problema similar (exactamente el mismo error).

El problema es que mientras se ejecutan varios casos de prueba que acceden a la base de datos varias veces, el primer caso de prueba abre la conexión a la base de datos y no la cierra. Cuando el segundo caso de prueba intenta abrir la conexión de base de datos de nuevo falla.

He leído algunas soluciones y finalmente se dio cuenta de que el problema era con la base de datos de apertura varias veces. Así que para ejecutar las pruebas con éxito, haga la siguiente configuración en su archivo TestCase.java (donde ha escrito sus casos de prueba):

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

Las dos funciones anteriores anotadas con "@Before" y "@After" se ejecutan antes y después de cada caso de prueba. Así pues, para después de cada caso de prueba debemos cerrar la conexión de la base de datos.

Esto y este enlaces ayudaron.

Comente por favor si hay algo mal en la solución o si mi comprensión de este error es incorrecta.

  • Ejemplo de Android SQLite
  • SQLiteOpenHelper - crear base de datos en tarjeta SD
  • ¿Cuándo debo llamar a close () en SQLiteOpenHelper utilizado por ContentProvider
  • SQLiteOpenHelper "onCreate" no se llama? (El DB no existe)
  • Archivo DB en carpeta de activos. ¿Se actualizará?
  • Confundido sobre CursorLoaders y usarlos con un SQLiteOpenHelper personalizado
  • El objeto de conexión de SQLite se filtró - Android
  • Cursor finalizado sin cerrar antes () Android
  • Actualizaciones de Android en Play Store
  • Intentando probar SQLiteOpenHelper pero getWritableDatabase () lanza Null
  • Error al leer la fila 0, columna 0 de una CursorWindow que tiene 0 filas, 64 columnas
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.