Предположим, у меня есть метод:
suspend fun manageSharedState() =
withContext(Dispatchers.IO) {
val result = runHeavyWork()
ensureActive()
writeSharedState(result.data)
return result.state
}
Я буду использовать этот код в android приложении как:
class MyActivity: AppCompatActivity, CoroutineScope by MainScope() {
fun onClick() {
launch {
progressView.show()
val result = try {
manager.manageSharedState()
} catch (e: CancellationException) {
activityLog.notifyCancelled()
return@launch
}
progressView.hide()
resultView.setState(result)
}
}
override fun onStop() {
cancel()
}
}
Есть ли способ, как провести модульное тестирование ensureActive()
выдает исключение отмены, в случае если задание отменяется пользователем, покидающим экран, таким образом, activityLog.notifyCancelled()
правильно называется?
Мне удалось это сделать (не уверен, что есть лучший способ):
launch (start = CoroutineStart.UNDISPATCHED) {
manager.manageSharedState()
}.cancelAndJoin()
Что, кажется, работает правильно, хотя я не могу контролировать, когда оно точно отменено. Кроме того, мой дизайн вырос с тех пор, и у меня есть:
suspend fun manageSharedState() =
withContext(Dispatchers.IO) {
try {
val result = runHeavyWork()
ensureActive()
writeSharedState(result.data)
return Result.Success(result.state)
} catch(e: CancellationException) {
return Result.Cancelled(e)
}
}
Там, где упомянутый подход к тестированию несовместим, поскольку я не могу получить результат изнутри запуска в модульном тесте и отменить его одновременно время. Есть идеи? Я знаю, что дизайн может быть немного ограничительным, но я взял идею из runCatching
и соединил ее с механизмом отмены, который делается исключениями. Который я считаю правильным. Я просто не знаю, как смоделировать это в модульном тесте. Спасибо.
Сноска: я использую комбо google.Truth, mockk.