SQLiteDatabase在测试运行之前关闭

时间:2017-01-15 17:54:57

标签: android database unit-testing junit android-sqlite

我有一个问题,我的数据库句柄在我的测试期间被关闭,我不知道为什么。

@Before方法正确运行,但@Test方法抛出异常:尝试重新打开已关闭的对象。我没有在我的代码中的任何地方关闭它,所以我不确定它是如何关闭的。

标记为@Test的方法是目前测试中唯一的方法,因此之前没有其他测试正在运行。

有谁能帮我理解这里发生的事情?

测试

@RunWith(AndroidJUnit4.class)
public class DatabaseTest {

    private Database subject;
    private SQLiteDatabase wDB;

    public DatabaseTest(){

        DbHelper helper = new DbHelper(InstrumentationRegistry.getTargetContext());
        subject = new Database(helper);
        wDB = helper.getWritableDatabase();

    }


    // remove any preexisting records from the database 
    @Before
    public void cleanSlate(){
        wDB.delete(Database.ITEMS_TABLE, null, null);
    }


    @Test
    public void testInsert(){

        Cursor c;
        Item i = getMockItem();
        subject.update(i);

        // (per below) DatabaseTest.java:46: 
        c = wDB.query(Database.ITEM_TABLE,Database.ALL_COLUMNS,null,null,null,null,null);

        //...

错误

java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/user/0/com.example.app.debug/databases/storage.db
at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1257)
at com.example.app.data.local.DatabaseTest.testInsert(DatabaseTest.java:46)

更新方法

public void update(Item item){

        SQLiteDatabase wDB = helper.getWritableDatabase();

        ContentValues cv = entryToContentValues(item);
        wDB.insertWithOnConflict(ITEM_TABLE, null, cv, SQLiteDatabase.CONFLICT_REPLACE );

        wDB.close();
    }

1 个答案:

答案 0 :(得分:0)

问题是您正在使用update方法关闭数据库,因此尝试在第46行运行查询时数据库已关闭。

一种解决方案是不在update方法中关闭数据库。但是,您应该在完成数据库后关闭它。

另一种解决方案可能是在查询之前但在getWriteableDatabase();之后调用update

其他解决方案可能只有一个单例,从而确保您只有一个实例/连接,然后只有在应用程序被销毁时才关闭数据库(我在我正在使用的应用程序中使用此方法)

P.S。您还应关闭游标,然后完成它们,因为它们可能导致太多打开错误/问题。我个人倾向于将光标关闭到活动onDestroy方法中。