Я работаю над приложением для Android, которое хранит пользовательские объекты "TimeSet" в базе данных. При взаимодействии с таблицей я использую AsyncTask
объекты для вставки и обновления строк. Во время тестирования я обнаружил, что эти задачи должны выполняться в определенном порядке (например, строка должна быть вставлена в базу данных перед ее обновлением), и когда они не выполняются должным образом, тесты не выполняются.
Насколько я понимаю, AsyncTask
работает по принципу "первым пришел - первым обслужен". В идеале я хочу, чтобы updateAsyncTask()
ждал, пока в таблице не появится какая-то строка, прежде чем это произойдет. Я пытался использовать объекты блокировки, чтобы предотвратить это, но у меня не получилось. Я также видел предложение, которое включало в себя отправку какого-то сообщения onPostExecute()
, но я не уверен, как заставить это работать для моего кода. Я относительно новичок в работе с Room в Android и считаю эту область особенно запутанной.
Типичный метод тестирования, который обновляет строку:
@Test
public void replaceTodaysTime() {
mActivityRule.getActivity().mTimeSetViewModel.insert(oldTimeSet);
mActivityRule.getActivity().sendTimeToDatabase(NEW_WORSE_TIME, EXERCISE_NAME, MOCK_DATE);
TimeSet timeSet = mActivityRule.getActivity().mTimeSetViewModel.getByName(EXERCISE_NAME);
assertEquals(NEW_WORSE_TIME, timeSet.getTodaystime());
assertNotSame(oldTimeSet.getTodaystime(), timeSet.getTodaystime());
}
ViewModel
связан с TimeSetRepository
public class TimeSetRepository {
public void insert(TimeSet timeSet) {
insertAsyncTask iat = new insertAsyncTask(mTimeSetDao);
timeSetLock.lock();
try {
iat.execute(timeSet);
} finally {
if(iat.getStatus() == AsyncTask.Status.FINISHED) {
timeSetLock.unlock();
}
}
}
public void updateByName(TimeSet timeSet) {
while (mAllTimeSets == null && mAllTimeSets.isEmpty()){
//do nothing!
}
updateAsyncTask uat = new updateAsyncTask(mTimeSetDao);
timeSetLock.lock();
try {
uat.execute(timeSet);
} finally {
if(uat.getStatus() == AsyncTask.Status.FINISHED) {
timeSetLock.unlock();
}
}
}
static class insertAsyncTask extends AsyncTask<TimeSet, Void, Void> {
private TimeSetDao mAsyncTimeSetDao;
insertAsyncTask(TimeSetDao dao) {
mAsyncTimeSetDao = dao;
}
@Override
protected Void doInBackground(final TimeSet... timeSets) {
mAsyncTimeSetDao.insertTimeSet(timeSets[0]);
return null;
}
}
private static class updateAsyncTask extends AsyncTask<TimeSet, Void, Void> {
private TimeSetDao mAsyncTimeSetDao;
updateAsyncTask(TimeSetDao dao) {
mAsyncTimeSetDao = dao;
}
@Override
protected Void doInBackground(final TimeSet... timeSets) {
mAsyncTimeSetDao.updateLastAccessed(timeSets[0].getExercisename(), timeSets[0].getLastaccessed());
mAsyncTimeSetDao.updateTodaysTime(timeSets[0].getExercisename(), timeSets[0].getTodaystime());
return null;
}
}
}
Я ожидаю, что oldTimeSet
будет вставлен в базу данных, затем будет обновлена строка, а затем, наконец, получит строку как объект. Когда это работает, переменная todaysTime
изменилась. Тем не менее, это не всегда работает, иногда возвращает время из oldTimeSet
, иногда timeSet
в методе теста является нулевым объектом и так далее. Я выполняю подобные действия в других тестах с похожими результатами. Я думаю, что если я смогу решить эту конкретную проблему, я смогу адаптировать решение к остальным тестам.
Спасибо за вашу помощь.