Android: Обновление базы данных из viewmodel и ее модульное тестирование

#android #junit #viewmodel #coroutine

Вопрос:

У меня в viewmodel есть метод, который сбрасывает строки в базе данных.

  fun resetScores() {
    viewModelScope.launch {
       for(player in players){ 
           
           player.level = 1
           player.score = 0
           playerDao.updatePlayer(player) // updates the DB
       }
    }
}

var players = mutableListOf<Player>() -- > players is a mutable list
 

У меня есть этот модульный тест для тестирования этого метода

 @Test
fun testResetScores() {
    val context = ApplicationProvider.getApplicationContext<Context>()
    val viewModel = PlayerViewModel(Phase10DataBase.getDatabase(context).playerDao)
    viewModel.players = mutableListOf(Player(1,"Player1",5,100),
        Player(2,"Player2",5,100),
        Player(3,"Player3",5,100))
    assertEquals(viewModel.players.get(1).score, 100)
    viewModel.resetScores()
    assertEquals(viewModel.players.get(1).score, 100)
}
 

И этот тест проходит, в то время как я ожидаю, что он провалится.
Похоже, что тест не ожидает завершения асинхронной операции с БД перед вызовом assert.
Как правильно это протестировать или нужно ли обновлять фактический рекорд сброса кода?

Ответ №1:

Используйте блокировку запуска, она блокирует до тех пор, пока сопрограмма не будет завершена

 @Test
fun testResetScores() = runBlocking {
    val context = ApplicationProvider.getApplicationContext<Context>()
    val viewModel = PlayerViewModel(Phase10DataBase.getDatabase(context).playerDao)
    viewModel.players = mutableListOf(Player(1,"Player1",5,100),
        Player(2,"Player2",5,100),
        Player(3,"Player3",5,100))
    assertEquals(viewModel.players.get(1).score, 100)
    viewModel.resetScores()
    assertEquals(viewModel.players.get(1).score, 100)
}
 

Комментарии:

1. это не исправило