При использовании сопрограмм kotlin, как я могу тестировать функцию, вызывающую функцию приостановки?

У меня такой класс

class SomeClass { fun someFun() { // ... Some synchronous code async { suspendfun() } } private suspend fun suspendFun() { dependency.otherFun().await() // ... other code } } 

Я хочу, чтобы unit test someFun() поэтому я написал модульный тест, который выглядит следующим образом:

 @Test fun testSomeFun() { runBlocking { someClass.someFun() } // ... verifies & asserts } 

Но это не работает, потому что runBlocking фактически не блокирует выполнение до тех пор, пока не будет выполнено все внутри runBlocking. Если я тестирую suspendFun() непосредственно внутри runBlocking он работает так, как ожидалось, но я хочу, чтобы иметь возможность тестировать someFun() все вместе.

Любой ключ, как проверить функцию с синхронизацией и асинхронным кодом?

Исправление асинхронных

Как реализовано, ваш someFun() просто «запустит и забудет» результат async . В результате runBlocking не runBlocking на этот тест.

Если возможно, make someFun() возвращает async 's Deferred а затем в runBlocking на нем.

 fun someFun(): Deferred<Unit> { // ... Some synchronous code return async { suspendFun() } } 

Затем тест:

 runBlocking { SomeClass().someFun().await() } 

Этот вопрос / ответ является хорошим ресурсом для получения дополнительной информации.

альтернативный: использовать запуск

Также можно избежать async использования функций suspend и готовой сопрограммы:

 suspend fun someFun() { // ... Some synchronous code suspendFun() } private suspend fun suspendFun() { delay(1000) println("executed") // ... other code } 

Тест использует launch и ждет его выполнения, используя join :

 runBlocking { launch { SomeClass().someFun() }.join() }