I am very fresh to RxJava library
, Reactive programming
& Room Database
. So I just learned recently that you have to test your Data Layer before working on it. So I am writing all these codes in java.
My Database class
@Database(entities = {SimpleTask.class},version = 1,exportSchema = false)
@TypeConverters({CalendarConverter.class})
public abstract class TaskDatabase extends RoomDatabase {
public abstract SimpleTaskDao simpleTaskDao();
}
My 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();
}
My Database Module
@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();
}
}
My SimpleTask Model
@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;
}
And now for the testing My 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);
}
}
so after running the insertTaskAndGetTask()
I get this error - java.lang.AssertionError: Value not present (latch = 0, values = 1, errors = 0, completions = 1)
Ofcourse I understand that the SimpleTask List being emitted by the observer is empty, but why?, I have tried researching this up but I am not able to figure it out!!!
You're not subscribing to the Completable
returned by this call, which means the upsert never happens:
database.simpleTaskDao().upsert(task);
You need to chain this call to your subsequent call to observeAll()
, to make sure they both happen, and they happen in the correct order:
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);
}