#android #unit-testing #kotlin #channel
#Android #модульное тестирование #котлин #канал
Вопрос:
Я начал учиться использовать канал, но у меня возникли проблемы с модульными тестами. Например, с классом
class TestOp (private val channel: Channellt;Stringgt;) { suspend fun op() { channel.send("new") } }
и чтобы проверить это
@ExtendWith(CoroutineExecutorExtension::class) @RunWith(JUnitPlatform::class) internal class TestOpTest{ @Test fun testOpReturnNew() { runBlockingTest { val channel = Channellt;Stringgt;() val test = TestOp(channel = channel) test.op() assertEquals("new", channel.receive()) } } }
где:
@ExperimentalCoroutinesApi class CoroutineExecutorExtension : InstantExecutorExtension() { private val testCoroutineDispatcher = TestCoroutineDispatcher() override fun beforeEach(context: ExtensionContext?) { super.beforeEach(context) Dispatchers.setMain(testCoroutineDispatcher) } override fun afterEach(context: ExtensionContext?) { super.afterEach(context) Dispatchers.resetMain() testCoroutineDispatcher.cleanupTestCoroutines() } } @ExperimentalCoroutinesApi open class InstantExecutorExtension : BeforeEachCallback, AfterEachCallback { override fun beforeEach(context: ExtensionContext?) { ArchTaskExecutor.getInstance() .setDelegate(object : TaskExecutor() { override fun executeOnDiskIO(runnable: Runnable) = runnable.run() override fun postToMainThread(runnable: Runnable) = runnable.run() override fun isMainThread(): Boolean = true }) } override fun afterEach(context: ExtensionContext?) { ArchTaskExecutor.getInstance().setDelegate(null) } }
Я получаю ошибку:
Эта работа еще не завершена java.lang.Исключение IllegalStateException: Эта работа еще не завершена в kotlinx.coroutines.Поддержка заданий.getCompletionExceptionOrNull(поддержка заданий. kt:1190) в kotlinx.сопрограммы.тест.TestBuildersKt.runBlockingTest(TestBuilders.kt:53) в kotlinx.coroutines.test.TestBuildersKt.runBlockingTest$по умолчанию(TestBuilders.kt:45)
Если я использую runBlocking
тест, он никогда не завершится.
Как правильно это проверить?
Комментарии:
1. Я думаю, что вы поставили delay(1000) перед утверждением.
Ответ №1:
Я исправил проблему, добавив:
@AfterEach fun tearDown() { viewModel.viewModelScope.cancel() }
таким образом, все сопрограммы отменяются, и проблема устраняется