测试使用 Room 和 RxJava 实现的数据库时出现“java.lang.AssertionError:值不存在”

问题描述 投票:0回答:1

我对

RxJava library
Reactive programming
Room Database
非常新鲜。所以我最近才了解到,在处理数据层之前必须先对其进行测试。所以我用java编写所有这些代码。

我的数据库课程

@Database(entities = {SimpleTask.class},version = 1,exportSchema = false)
@TypeConverters({CalendarConverter.class})
public abstract class TaskDatabase extends RoomDatabase {

    public abstract SimpleTaskDao simpleTaskDao();

}

我的SimpleTaskDao

@Dao
public interface SimpleTaskDao {

    @Query("SELECT * FROM simpleTask")
    public Observable<List<SimpleTask>> observeAll();

    @Upsert
    public Completable upsert(SimpleTask task);

    @Upsert
    public Completable upsertAll(List<SimpleTask> taskList);

    @Query("UPDATE simpleTask SET `check`=:check WHERE `id`=:id")
    public Completable updateCompleted(int id, boolean check);

    @Query("DELETE FROM simpleTask")
    public Completable deleteAll();

}

我的数据库模块

@Module
@InstallIn(SingletonComponent.class)
public class DatabaseModule{
    final String DATABASE_NAME = "not_disclosing_this_here";

    @Singleton
    @Provides
    TaskDatabase provideDatabase(@ApplicationContext Context context){
        return Room.databaseBuilder(context.getApplicationContext(),TaskDatabase.class,DATABASE_NAME).build();
    }

    @Provides
    SimpleTaskDao provideSimpleTaskDao(TaskDatabase database) {
        return database.simpleTaskDao();
    }
}

我的 SimpleTask 模型

@Entity(
        tableName = "simpleTask"
)
final public class SimpleTask {
    @PrimaryKey(autoGenerate = true)
    private int id;
    @ColumnInfo(name = "title")
    private String title;
    @ColumnInfo(name = "details")
    private String details;
    @ColumnInfo(name = "alarm")
    @TypeConverters(CalendarConverter.class)
    private Calendar alarm;
    @ColumnInfo(name = "repeat")
    private int repeat;
    @ColumnInfo(name = "check")
    private boolean check;

    @Ignore
    public SimpleTask(){}
    @Ignore
    public SimpleTask(String input){
        setTitle(input);
        setDetails("");
        setAlarm(null);
        setRepeat(0);
        setCheck(false);
    }
    @Ignore
    public SimpleTask(String title, String details, Calendar alarm, int repeat, boolean check){
        setTitle(title);
        setDetails(details);
        setAlarm(alarm);
        setRepeat(repeat);
        setCheck(check);
    }
    public SimpleTask(int id,String title, String details, Calendar alarm, int repeat, boolean check){
        setId(id);
        setTitle(title);
        setDetails(details);
        setAlarm(alarm);
        setRepeat(repeat);
        setCheck(check);
        Log.d("data creation","simple task created - "+id+title+alarm.toString()+repeat+check);
    }

    @Ignore
    public SimpleTask(String title, String desc) {
        setTitle(title);
        setDetails(desc);
    }

    @Ignore
    public SimpleTask(int id,String title, String desc) {
        setId(id);
        setTitle(title);
        setDetails(desc);
    }


    //    getter and setters

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public boolean isCheck() {
        return check;
    }

    public void setCheck(boolean check) {
        this.check = check;
    }

    public int getRepeat() {
        return repeat;
    }

    public void setRepeat(int repeat) {
        this.repeat = repeat;
    }

    public String getDetails() {
        return details;
    }

    public void setDetails(String details) {
        this.details = details;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Calendar getAlarm() {
        return alarm;
    }

    public void setAlarm(Calendar alarm) {
        this.alarm = alarm;
    }

现在进行测试 我的 SimpleTaskDaoTest

public class SimpleTaskDaoTest {
    private TaskDatabase database;

    @Before
    public void initDb(){
        database = Room.inMemoryDatabaseBuilder(
                getApplicationContext(),
                TaskDatabase.class
        ).allowMainThreadQueries().build();
    }

    @Test
    public void insertTaskAndGetTask(){

        SimpleTask task = new SimpleTask(34,"title","description", Calendar.getInstance(),1,false);

        database.simpleTaskDao().upsert(task);

        TestObserver<List<SimpleTask>> testObserver = new TestObserver<>();
        database.simpleTaskDao().observeAll()
                .firstElement()
                .toObservable()
                .subscribe(testObserver);

        testObserver.awaitTerminalEvent();
        testObserver.assertNoErrors();
        testObserver.assertValue(taskList -> taskList.size()==1);

    }
}

因此运行

insertTaskAndGetTask()
后我收到此错误 -
java.lang.AssertionError: Value not present (latch = 0, values = 1, errors = 0, completions = 1)

当然,我知道观察者发出的 SimpleTask 列表是空的,但是为什么?,我尝试过研究这个问题,但我无法弄清楚!

java android database rx-java android-room
1个回答
0
投票

您没有订阅此调用返回的

Completable
,这意味着更新插入永远不会发生:

    database.simpleTaskDao().upsert(task);

您需要将此调用链接到后续对

observeAll()
的调用,以确保它们都发生,并且它们以正确的顺序发生:

 public void insertTaskAndGetTask(){

        SimpleTask task = new SimpleTask(34,"title","description", Calendar.getInstance(),1,false);
        TestObserver<List<SimpleTask>> testObserver = new TestObserver<>();
        database.simpleTaskDao().upsert(task)
                .andThen(database.simpleTaskDao().observeAll())
                .firstElement()
                .toObservable()
                .subscribe(testObserver);

        testObserver.awaitTerminalEvent();
        testObserver.assertNoErrors();
        testObserver.assertValue(taskList -> taskList.size()==1);

    }
© www.soinside.com 2019 - 2024. All rights reserved.