1 /* 2 * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 package kotlinx.coroutines.test 5 6 import kotlinx.coroutines.* 7 import kotlinx.coroutines.test.internal.* 8 import kotlin.coroutines.* 9 import kotlin.test.* 10 11 class TestDispatchersTest: OrderedExecutionTestBase() { 12 13 @BeforeTest setUpnull14 fun setUp() { 15 Dispatchers.setMain(StandardTestDispatcher()) 16 } 17 18 @AfterTest tearDownnull19 fun tearDown() { 20 Dispatchers.resetMain() 21 } 22 23 /** Tests that asynchronous execution of tests does not happen concurrently with [AfterTest]. */ 24 @Test <lambda>null25 fun testMainMocking() = runTest { 26 val mainAtStart = TestMainDispatcher.currentTestDispatcher 27 assertNotNull(mainAtStart) 28 withContext(Dispatchers.Main) { 29 delay(10) 30 } 31 withContext(Dispatchers.Default) { 32 delay(10) 33 } 34 withContext(Dispatchers.Main) { 35 delay(10) 36 } 37 assertSame(mainAtStart, TestMainDispatcher.currentTestDispatcher) 38 } 39 40 /** Tests that the mocked [Dispatchers.Main] correctly forwards [Delay] methods. */ 41 @Test <lambda>null42 fun testMockedMainImplementsDelay() = runTest { 43 val main = Dispatchers.Main 44 withContext(main) { 45 delay(10) 46 } 47 withContext(Dispatchers.Default) { 48 delay(10) 49 } 50 withContext(main) { 51 delay(10) 52 } 53 } 54 55 /** Tests that [Distpachers.setMain] fails when called with [Dispatchers.Main]. */ 56 @Test testSelfSetnull57 fun testSelfSet() { 58 assertFailsWith<IllegalArgumentException> { Dispatchers.setMain(Dispatchers.Main) } 59 } 60 61 @Test <lambda>null62 fun testImmediateDispatcher() = runTest { 63 Dispatchers.setMain(ImmediateDispatcher()) 64 expect(1) 65 withContext(Dispatchers.Main) { 66 expect(3) 67 } 68 69 Dispatchers.setMain(RegularDispatcher()) 70 withContext(Dispatchers.Main) { 71 expect(6) 72 } 73 74 finish(7) 75 } 76 77 private inner class ImmediateDispatcher : CoroutineDispatcher() { isDispatchNeedednull78 override fun isDispatchNeeded(context: CoroutineContext): Boolean { 79 expect(2) 80 return false 81 } 82 dispatchnull83 override fun dispatch(context: CoroutineContext, block: Runnable) = throw RuntimeException("Shouldn't be reached") 84 } 85 86 private inner class RegularDispatcher : CoroutineDispatcher() { 87 override fun isDispatchNeeded(context: CoroutineContext): Boolean { 88 expect(4) 89 return true 90 } 91 92 override fun dispatch(context: CoroutineContext, block: Runnable) { 93 expect(5) 94 block.run() 95 } 96 } 97 } 98