即使使用Mockito在Android中通过了单元测试,也始终会出现线程错误 [英] Always get thread error even if unit test passes in Android using Mockito
问题描述
即使测试通过,我也总是会出错,不知道为什么.这次我正在检查是否有null指针,如果视图为null.
I always get an error even if a test passes and not sure why. This time i was checking there is a null pointer if the view is null.
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mockView = mock(CollectionContract.View.class);
// Get a reference to the class under test
presenter = new CollectionPresenter(repository, mockView);
}
@Test(expected = NullPointerException.class)
public void testShowingUIWhenViewIsNull() {
presenter = new CollectionPresenter(repository, null);
verify(mockView).showAddCollection();
}
这是堆栈跟踪:
Exception in thread "Thread-2" android.database.sqlite.SQLiteException: Cannot prepare statement, base error code: -92
at org.robolectric.shadows.ShadowSQLiteConnection$Connections.getSqliteException(ShadowSQLiteConnection.java:632)
at org.robolectric.shadows.ShadowSQLiteConnection$Connections.execute(ShadowSQLiteConnection.java:601)
at org.robolectric.shadows.ShadowSQLiteConnection$Connections.prepareStatement(ShadowSQLiteConnection.java:525)
at org.robolectric.shadows.ShadowSQLiteConnection.nativePrepareStatement(ShadowSQLiteConnection.java:93)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(SQLiteConnection.java)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
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.compileStatement(SQLiteDatabase.java:994)
at android.database.DatabaseUtils.longForQuery(DatabaseUtils.java:811)
at android.database.sqlite.SQLiteDatabase.getVersion(SQLiteDatabase.java:864)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:241)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at co.uk.rushorm.android.AndroidRushStatementRunner.runRaw(AndroidRushStatementRunner.java:37)
at co.uk.rushorm.core.RushCore$12.statementCreated(RushCore.java:473)
at co.uk.rushorm.core.implementation.ReflectionTableStatementGenerator.generateStatements(ReflectionTableStatementGenerator.java:46)
at co.uk.rushorm.core.RushCore.createTables(RushCore.java:469)
at co.uk.rushorm.core.RushCore.access$200(RushCore.java:39)
at co.uk.rushorm.core.RushCore$1.run(RushCore.java:130)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.util.concurrent.ExecutionException: com.almworks.sqlite4java.SQLiteException: [-92] DB[1] is not confined or already disposed
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly(Uninterruptibles.java:142)
at org.robolectric.shadows.ShadowSQLiteConnection$Connections.execute(ShadowSQLiteConnection.java:596)
at org.robolectric.shadows.ShadowSQLiteConnection$Connections.prepareStatement(ShadowSQLiteConnection.java:525)
at org.robolectric.shadows.ShadowSQLiteConnection.nativePrepareStatement(ShadowSQLiteConnection.java:93)
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.robolectric.internal.bytecode.ShadowWrangler$ShadowMethodPlan.run(ShadowWrangler.java:548)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(SQLiteConnection.java)
at android.database.sqlite.SQLiteConnection.$$robo$$acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java)
at android.database.sqlite.SQLiteConnection.$$robo$$prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java)
at android.database.sqlite.SQLiteSession.$$robo$$prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java)
at android.database.sqlite.SQLiteProgram.$$robo$$__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.$$robo$$compileStatement(SQLiteDatabase.java:994)
at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java)
at android.database.DatabaseUtils.$$robo$$longForQuery(DatabaseUtils.java:811)
at android.database.DatabaseUtils.longForQuery(DatabaseUtils.java)
at android.database.sqlite.SQLiteDatabase.$$robo$$getVersion(SQLiteDatabase.java:864)
at android.database.sqlite.SQLiteDatabase.getVersion(SQLiteDatabase.java)
at android.database.sqlite.SQLiteOpenHelper.$$robo$$getDatabaseLocked(SQLiteOpenHelper.java:241)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java)
at android.database.sqlite.SQLiteOpenHelper.$$robo$$getWritableDatabase(SQLiteOpenHelper.java:163)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java)
... 7 more
Caused by: com.almworks.sqlite4java.SQLiteException: [-92] DB[1] is not confined or already disposed
at com.almworks.sqlite4java.SQLiteConnection.checkThread(SQLiteConnection.java:1386)
at com.almworks.sqlite4java.SQLiteConnection.prepare(SQLiteConnection.java:451)
at com.almworks.sqlite4java.SQLiteConnection.prepare(SQLiteConnection.java:542)
at com.almworks.sqlite4java.SQLiteConnection.prepare(SQLiteConnection.java:529)
at org.robolectric.shadows.ShadowSQLiteConnection$Connections$2.call(ShadowSQLiteConnection.java:529)
at org.robolectric.shadows.ShadowSQLiteConnection$Connections$2.call(ShadowSQLiteConnection.java:525)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
... 1 more
如果视图存在,为什么sql异常会出现在show view ui上?坚持下去,因为我几乎可以在每个测试中找到它.任何想法都很棒.谢谢.
Why would sql exception appear on a show view ui if view exists? Stuck on this, for i find it in every test almost. Any ideas would be great. Thank you.
推荐答案
从此行判断:
Caused by: com.almworks.sqlite4java.SQLiteException: [-92] DB[1] is not confined or already disposed
并按上一行
at com.almworks.sqlite4java.SQLiteConnection.checkThread(SQLiteConnection.java:1386)
可以得出结论,checkThread
所做的是检查,是否在最初创建数据库的线程上执行查询,并且该检查没有通过.
one may conclude, that what checkThread
does is it checks, whether the query is being performed on a thread that the database has originally been created on, and that check does NOT pass.
确保在同一线程上创建和查询数据库.基本上,您必须为数据库操作指定一个单独的线程.
Make sure you are creating and querying the database on the same thread. Basically, you have to dedicate a separate thread for database operations.