Skip to content

Commit

Permalink
Cleanup TestCoroutineScope documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
qwwdfsad committed Apr 25, 2019
1 parent fe820ba commit c9867b2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 21 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ suspend fun main() = coroutineScope {
* Integration with `Window`.
* [test](kotlinx-coroutines-test/README.md) — test utilities for coroutines
* `Dispatchers.setMain` to override `Dispatchers.Main` in tests.
* `TestCoroutineScope` to test suspending functions and coroutines.
* [debug](kotlinx-coroutines-debug/README.md) — debug utilities for coroutines.
* `DebugProbes` API to probe, keep track of, print and dump active coroutines.
* `CoroutinesTimeout` test rule to automatically dump coroutines on test timeout.
Expand Down
42 changes: 21 additions & 21 deletions kotlinx-coroutines-test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ coroutine. Any calls to `delay` will automatically advance time.

```kotlin
@Test
fun testFoo() = runBlockingTest { // a coroutine with a extra test control
fun testFoo() = runBlockingTest { // a coroutine with an extra test control
val actual = foo()
// ...
}

suspend fun foo() {
delay(1_000) // auto-advances without delay due to runBlockingTest
delay(1_000) // auto-advances without delay due to runBlockingTest
// ...
}
```
Expand All @@ -105,8 +105,8 @@ fun testFooWithLaunch() = runBlockingTest {
fun CoroutineScope.foo() {
// This coroutines `Job` is not shared with the test code
launch {
bar() // executes eagerly when foo() is called due to runBlockingTest
println(1) // executes eagerly when foo() is called due to runBlockingTest
bar() // executes eagerly when foo() is called due to runBlockingTest
println(1) // executes eagerly when foo() is called due to runBlockingTest
}
}

Expand All @@ -129,24 +129,24 @@ To control time in the test you can use the [DelayController] interface. The blo
fun testFooWithLaunchAndDelay() = runBlockingTest {
foo()
// the coroutine launched by foo has not completed here, it is suspended waiting for delay(1_000)
advanceTimeBy(1_000) // progress time, this will cause the delay to resume
advanceTimeBy(1_000) // progress time, this will cause the delay to resume
// foo() coroutine launched by foo has completed here
// ...
}

suspend fun CoroutineScope.foo() {
launch {
println(1) // executes eagerly when foo() is called due to runBlockingTest
delay(1_000) // suspends until time is advanced by at least 1_000
println(2) // executes after advanceTimeBy(1_000)
println(1) // executes eagerly when foo() is called due to runBlockingTest
delay(1_000) // suspends until time is advanced by at least 1_000
println(2) // executes after advanceTimeBy(1_000)
}
}
```

*Note:* `runBlockingTest` will always attempt to auto-progress time until all coroutines are completed just before
exiting. This is a convenience to avoid having to call [advanceUntilIdle][DelayController.advanceUntilIdle]
as the last line of many common test cases.
If any coroutines cannot complete by advancing time, a [UncompletedCoroutinesError] is thrown.
If any coroutines cannot complete by advancing time, an [UncompletedCoroutinesError] is thrown.

### Testing `withTimeout` using `runBlockingTest`

Expand All @@ -159,16 +159,16 @@ example an uncompleted `Deferred<Foo>` is provided to the function under test vi
```kotlin
@Test(expected = TimeoutCancellationException::class)
fun testFooWithTimeout() {
val uncompleted = CompletableDeferred<Foo>() // this Deferred<Foo> will never complete
val uncompleted = CompletableDeferred<Foo>() // this Deferred<Foo> will never complete
foo(uncompleted)
advanceTimeBy(1_000) // advance time, which will cause the timeout to throw an exception
advanceTimeBy(1_000) // advance time, which will cause the timeout to throw an exception
// ...
}

fun CoroutineScope.foo(resultDeferred: Deferred<Foo>) {
launch {
withTimeout(1_000) {
resultDeferred.await() // await() will suspend forever waiting for uncompleted
resultDeferred.await() // await() will suspend forever waiting for uncompleted
// ...
}
}
Expand Down Expand Up @@ -196,19 +196,19 @@ fun testFooWithPauseDispatcher() = runBlockingTest {
pauseDispatcher {
foo()
// the coroutine started by foo has not run yet
runCurrent() // the coroutine started by foo advances to delay(1_000)
runCurrent() // the coroutine started by foo advances to delay(1_000)
// the coroutine started by foo has called println(1), and is suspended on delay(1_000)
advanceTimeBy(1_000) // progress time, this will cause the delay to resume
advanceTimeBy(1_000) // progress time, this will cause the delay to resume
// the coroutine started by foo has called println(2) and has completed here
}
// ...
}

fun CoroutineScope.foo() {
launch {
println(1) // executes after runCurrent() is called
delay(1_000) // suspends until time is advanced by at least 1_000
println(2) // executes after advanceTimeBy(1_000)
println(1) // executes after runCurrent() is called
delay(1_000) // suspends until time is advanced by at least 1_000
println(2) // executes after advanceTimeBy(1_000)
}
}
```
Expand Down Expand Up @@ -250,7 +250,7 @@ In simple cases, tests can use the [TestCoroutineScope] created by [runBlockingT
```kotlin
@Test
fun testFoo() = runBlockingTest {
foo() // runBlockingTest passed in a TestCoroutineScope as this
foo() // runBlockingTest passed in a TestCoroutineScope as this
}

fun CoroutineScope.foo() {
Expand Down Expand Up @@ -329,7 +329,7 @@ important to ensure that [cleanupTestCoroutines][TestCoroutineDispatcher.cleanup

```kotlin
class TestClass {
val testDispatcher = TestCoroutineDispatcher()
private val testDispatcher = TestCoroutineDispatcher()

@Before
fun setup() {
Expand Down Expand Up @@ -398,7 +398,7 @@ either dependency injection, a service locator, or a default parameter.
```kotlin
suspend fun veryExpensiveOne() = withContext(Dispatchers.Default) {
delay(1_000)
1 // for very expensive values of 1
1 // for very expensive values of 1
}
```

Expand All @@ -409,7 +409,7 @@ directly, there is no need to inject a `TestCoroutineDispatcher` into this funct

```kotlin
suspend fun veryExpensiveTwo() = withContext(Dispatchers.Default) {
2 // for very expensive values of 2
2 // for very expensive values of 2
}
```

Expand Down

0 comments on commit c9867b2

Please sign in to comment.