使用Room与RxJava实现数据库测试时遇AssertionError问题求助
解决方案
核心问题
测试代码中upsert(task)是异步的Completable操作,你没有等待它执行完成就立即订阅observeAll()查询数据,此时数据库还没完成插入操作,所以查询返回空列表,导致断言失败。
修正后的测试代码
public class SimpleTaskDaoTest { private TaskDatabase database; private SimpleTaskDao taskDao; @Before public void initDb(){ // 测试环境标准上下文获取方式 database = Room.inMemoryDatabaseBuilder( ApplicationProvider.getApplicationContext(), TaskDatabase.class ).allowMainThreadQueries().build(); taskDao = database.simpleTaskDao(); } @After public void closeDb(){ // 测试结束后清理数据库资源 if (database != null) { database.close(); } } @Test public void insertTaskAndGetTask() { SimpleTask task = new SimpleTask(34,"title","description", Calendar.getInstance(),1,false); // 等待upsert操作完成,确保数据写入数据库 taskDao.upsert(task).blockingAwait(); // 用RxJava内置方法简化TestObserver创建 TestObserver<List<SimpleTask>> testObserver = taskDao.observeAll() .firstElement() .toObservable() .test(); testObserver.awaitTerminalEvent(); testObserver.assertNoErrors(); testObserver.assertValue(taskList -> taskList.size() == 1); // 可选:验证返回数据与插入数据一致 testObserver.assertValue(taskList -> { SimpleTask resultTask = taskList.get(0); return resultTask.getId() == 34 && resultTask.getTitle().equals("title"); }); } }
关键修改说明
- 等待异步操作完成:调用
blockingAwait()让测试线程等待upsert执行完毕,保证数据持久化后再查询。 - 规范上下文获取:测试中使用
ApplicationProvider.getApplicationContext()是Android测试的标准做法(需依赖androidx.test:core库)。 - 添加资源清理:
@After方法中关闭数据库,避免测试后资源泄漏。 - 简化TestObserver使用:用
test()方法直接创建并订阅观察者,代码更简洁不易出错。
额外注意点
- 你的
SimpleTask实体设置了@PrimaryKey(autoGenerate = true),但测试中手动指定了id=34,这会覆盖Room的自动生成逻辑。若要测试自动生成id场景,应使用不带id的构造函数插入数据,再验证生成的id。 - 确保
CalendarConverter实现正确,否则日期类型的存储和反序列化可能出错,导致数据无法正常查询。
内容的提问来源于stack exchange,提问作者Arya_
相关产品推荐
相关产品推荐

