runTest runBlocking

runTest()與this

runTest()函式中,建立一個TestScope()的物件,讓testScope物件成為呼叫block()函式的呼叫者,kotlin稱這是「函式接收者」,會把testScope物件作為this物件傳入block()中。
最後會把testScope新物件作為函式傳回值傳回。

1
2
3
4
5
6
7
8
// 簡化版(概念說明用)
fun runTest(block: TestScope.() -> Unit): TestScope {
    // 建立一個TestScope()的物件
    val testScope = TestScope()
    // testScope物件.呼叫block()函式
    testScope.block()
    return testScope
}

所以印出的this就是TestScope()的物件。

1
2
3
4
  @Test
  fun coroutin13() = runTest {
    println(this)
  }
TestScope[test started]

之前在擴展函式apply()的文章有提到,apply()裡面的this是呼叫apply()的物件。
下面程式中,apply()的this是”Hello world”,呼叫擴展函式的物件。

1
2
3
"Hello world".apply { 
   println(this)
}
Hello world

而這邊是建立新的物件,使用新的物件呼叫lambda,this就會指向新的物件,apply()擴展函式會把呼叫者(接收者),作為傳回值傳回。
印出物件的類別。

this::class.simpleName
1
2
3
4
5
6
7
8
9
  @Test
  fun test() {
    val result = StringBuilder().apply {
      println("obj = ${this::class.simpleName}")
      append("Hello")
      append(" World!")
    }
    println(result)
  }

runTest runBlocking

接下來的測試會使用runTest或runBlocking來測試協程。
使用junit的@Test,來協助測試。

1
2
3
4
5
6
7
8
import kotlinx.coroutines.test.runTest
import org.junit.Test

class Test01 {
  @Test
  fun coroutin01() = runTest {
  }
}

runBlocking與listof

runBlocking與runTest有類似功能。

但以下程式碼,runTest會自動執行list中的協程,而runBlocking不會自動執行。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
fun coroutin14() = runTest {
  val job = Job()
  val list = listOf(
    launch(job) {
      delay(1000)
      println("list[0] finish")
    },
    launch(job) {
      delay(2000)
      println("list[1] finish")
    })
}
list[0] finish
list[1] finish
1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
fun coroutin14() = runBlocking {
  val job = Job()
  val list = listOf(
    launch(job) {
      delay(1000)
      println("list[0] finish")
    },
    launch(job) {
      delay(2000)
      println("list[1] finish")
    })
}

呼叫start()函式,才會執行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
fun coroutin14() = runBlocking {
  val job = Job()
  val list = listOf(
    launch(job) {
      delay(1000)
      println("list[0] finish")
    },
    launch(job) {
      delay(2000)
      println("list[1] finish")
    })
  job.start()
}
list[0] finish
list[1] finish

results matching ""

    No results matching ""