I have SimulationService that holds simple logic to loop until a stop() function has been called. When using Spring Boot Rest that works fine - since web requests to a spring application are scoped into threads and therefore can "interrupt" the main thread running in a loop by changing state - in this case a simple boolean flag that stops the while loop.
Now I wanted to test this behavior for a reason:
internal class SimulationServiceTest {
private val simulateservice = SimulationService()
@Test
fun `should update the amount of ticks ran by the simulation`(): Unit = runBlocking {
assertThat(SimulationContext.ticks).isEqualTo(0)
launch(start = CoroutineStart.UNDISPATCHED, context = Dispatchers.IO) {
simulateservice.start()
}
sleep(1000)
launch(start = CoroutineStart.UNDISPATCHED, context = Dispatchers.Default) {
simulateservice.stop()
}
assertThat(SimulationContext.ticks).isGreaterThan(0)
}
}
In this case I just want to test if the SimulationService does keep track of the ticks or iterations the while loop has been gone through.
However I am not able to mimic the behavior of web requests with launch or async.
It behaves just like it does when I use it without CoRoutines.
When start() is called - the main thread is stuck in a loop. Therefore I need a CoRoutine that launches to actually access that thread.
I read about CoRoutines not being multiple different threads. However I read that for CoRoutines there is at least one new thread created - otherwise there wouldn't be a way to become asynchronous.
I though that Dispatchers represent the "new threads". So CoRoutine can run on the DEFAULT, MAIN and IO thread. For me that is DEFAULT & IO shouldn't be the same, right?
How is it happening now - that my CoRoutines still seem to be async onto one thread? The test process is running in indefinitely just like it would act on a common thread.
Here is an example how it does with with Java Executors thread service:
internal class SimulationServiceTest {
private val simulateservice = SimulationService()
@Test
fun `should update the amount of ticks ran by the simulation`() {
assertThat(SimulationContext.ticks).isEqualTo(0)
val executor = Executors.newSingleThreadExecutor()
executor.submit {
simulateservice.start()
}
sleep(1000)
simulateservice.stop()
assertThat(SimulationContext.ticks).isGreaterThan(0)
}
}