Kotlin Отмена модульного теста сопрограмм - PullRequest
0 голосов
/ 16 марта 2020

Предположим, у меня есть метод:

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.

...