【问题标题】:Android unit tests - SQLiteReadOnlyDatabaseException: Attempt to write a readonly database (code 1032)Android 单元测试 - SQLiteReadOnlyDatabaseException:尝试写入只读数据库(代码 1032)
【发布时间】:2017-03-12 08:36:21
【问题描述】:

我刚刚为我的 CRUD 实现创建了单元测试,我遇到了这个奇怪的问题。当测试一个一个运行时,它们都通过了。但是当我想运行整个套件时,它们会因错误而失败

android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (code 1032)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1471)
at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1367)
at cz.pikadorama.simpleorm.DatabaseSanityTest.testDelete(DatabaseSanityTest.java:55)

这是代码

@Before
public void prepareDatabase() throws InstantiationException, IllegalAccessException {
    Context context = InstrumentationRegistry.getTargetContext();
    context.deleteDatabase(DATABASE_NAME);
    DbManager.registerHelper(new TestSQLiteHelper(context), new Class<?>[]{TestEntity.class});
}

@Test
public void testDelete() {
    Dao<TestEntity> dao = DaoManager.getDao(TestEntity.class);
    TestEntity entity = new TestEntity();
    dao.create(entity);  
    dao.delete(entity);
    assertEquals(0, dao.findAll().size());
}

// other tests for insert, update, ... follow

顺便说一句,DAO 实现总是以sqliteOpenHelper.getWritableDatabase() 打开可写数据库。

【问题讨论】:

  • 您是否在测试之间的任何时候关闭数据库?
  • 尝试将您当前的@Before 方法更改为@BeforeClass 方法。它解决了问题吗?
  • 是的,最后我尝试将prepare移动到@BeforeClass并清理数据库而不是在每次测试之前删除它。
  • 那么,它确实解决了问题,对吧?

标签: android sqlite android-sqlite


【解决方案1】:

这与 DbManager 和 DaoMaster 是单例(以及底层数据库,我想)这一事实有关:@Before 中的代码在每次测试之前被调用,这会搞砸类中的事情,这可能应该只需启动一次。

@Before 注释更改为@BeforeClass 以便只执行一次初始化。

【讨论】:

  • 嗯,这不是问题。问题是,当您在@Before 中删除数据库并且每次都运行它时,测试是如此之快以至于实际上需要编写一个“热门日志”。但默认情况下,Java 连接是只读的,您不能使用该连接编写日志。
  • @user219882,我认为你错了。您可以删除@Before 中的数据库,但是您必须确保再次正确初始化它。我确实认为您的问题是对DbManager.registerHelper() 的调用没有正确进行初始化。无论如何,既然这个答案解决了您的问题,请考虑接受它)
猜你喜欢
  • 2016-05-07
  • 2018-07-03
  • 1970-01-01
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
  • 2016-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多