2016-01-12 16 views
6

Tôi đang cố gắng chạy nhiều thử nghiệm với Robolectric 3.0 + Gradle sử dụng SQLite (OpenHelper) làm cơ sở dữ liệu. Chạy từng thử nghiệm đơn hoạt động tốt, nhưng bắt đầu toàn bộ bộ kiểm tra luôn dẫn đến RuntimeException trong lần kiểm tra thứ hai.Robolectric: chạy nhiều thử nghiệm không thành công

Đây là hình mẫu thử nghiệm của tôi, không hoạt động.

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

Đã thử một số giải pháp như Reseting singleton với đoạn mã sau, kết thúc trong FieldNotfoundException hoặc NullPointerException, vì vậy đã không làm việc.

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

Chỉnh sửa: sửa lỗi bằng cách xóa sendUpdateEvent() của AppInstanceUpdater của D360Sdk.

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

Ah, một lần nữa khởi tạo thư viện trong lớp ứng dụng. Hãy xem giải pháp này http://stackoverflow.com/questions/34695552/robolectric-with-activeandroid-setup-nullpointerexception-on-activeandroidrefle –

+0

+1 Đối với giải pháp của bạn! Sau hai ngày thất bại, bạn cứu mạng tôi! Ví dụ cài đặt lại chính xác là những gì tôi đang tìm kiếm! –

Trả lời

5

Đây là câu hỏi cũ nhưng có thể giải pháp này có thể giúp ai đó khi tôi gặp phải vấn đề tương tự (cùng lỗi chính xác).

Vấn đề là trong khi chạy nhiều trường hợp thử nghiệm đang truy cập cơ sở dữ liệu nhiều lần, trường hợp kiểm tra đầu tiên sẽ mở kết nối tới cơ sở dữ liệu và không đóng nó. Khi thử nghiệm lần thứ hai trường hợp cố gắng để mở kết nối cơ sở dữ liệu một lần nữa nó không thành công.

Tôi đọc một số giải pháp và cuối cùng đã tìm ra rằng vấn đề là mở cơ sở dữ liệu nhiều lần. Vì vậy, để chạy thử nghiệm thành công, thực hiện các cấu hình sau đây trong tập tin TestCase.java của bạn (nơi bạn đã viết các trường hợp thử nghiệm của bạn):

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

Hai chức năng trên chú thích với "@Before" và "@After" chạy trước và sau mọi trường hợp thử nghiệm. Vì vậy, đối với sau mỗi trường hợp kiểm tra, chúng ta nên đóng kết nối cơ sở dữ liệu.

Thisthis liên kết đã trợ giúp.

Vui lòng nhận xét nếu có điều gì đó sai trong giải pháp hoặc nếu sự hiểu biết của tôi về lỗi này là sai.

+0

@Downvoter bạn có thể vui lòng bình luận ở đây những gì không hoạt động. –

Các vấn đề liên quan