In previous post, we have gone through most of the key concepts and methods in Coroutine:
Kotlin Coroutines Table Content
1, Introduction to Coroutine in Kotlin
2, Non-blocking in Kotlin Coroutines
3, Start and Suspend a Coroutine in Kotlin
However, we haven't talked about runBlocking
yet, which is a function provided by the kotlinx.coroutines
library in Kotlin. It is used to start a new coroutine that runs synchronously on the current thread and blocks the thread until the coroutine completes.
runBlocking
is typically used to start a coroutine from a non-coroutine context, such as a main function, a unit test, or a Java method. It allows you to start a coroutine and wait for it to complete without having to manually manage the lifecycle of the coroutine.
Here's an example of how you might use runBlocking
to start a coroutine and wait for it to complete:
import kotlinx.coroutines.*
fun main() {
runBlocking {
val result = async {
delay(1000)
"Hello, World!"
}
println(result.await())
}
}
In this example, the runBlocking
function starts a new coroutine that runs on the current thread (the main thread in this case). Inside the coroutine, we use the async
function to start another coroutine that sleeps for one second and then returns a string. The await()
function is used to wait for the result of the async coroutine and the result is printed out after 1 sec.
It's important to note that runBlocking
is a blocking function, so it should be used with caution. It can be useful for small test cases, but for longer-running coroutines it is recommended to use the launch
or async
functions and manage the lifecycle of the coroutines manually, in order to not block the main thread.
RunBlocking for Unit testing
runBlocking
often is used in unit tests to start a coroutine and wait for it to complete. This allows you to test coroutines in a synchronous manner, making it easier to write tests and assert on the results.
Here's an example of how you might use runBlocking
in a JUnit test:
import kotlinx.coroutines.*
import org.junit.Test
class MyTests {
@Test
fun testCoroutine() = runBlocking {
val result = async {
delay(1000)
"Hello, World!"
}
assertEquals("Hello, World!", result.await())
}
}
In this example, we use the runBlocking
function to start a new coroutine in the context of the test method. The coroutine sleeps for 1 sec and returns a string, which is then asserted in the test.
Using runBlocking
in unit tests can make it easier to write tests and assert on the results of coroutines, but it's important to be aware that it makes the test synchronous, so it will block the current thread until the coroutine completes. Also, it's important to make sure that your coroutines are properly isolated from other parts of the system, by using Dispatchers.Unconfined or test dispatchers, to avoid unexpected results in your test.