'Coroutines test with spek

i'm try to write test for my viewModel function with coroutines. When request is success -> the data is sent to LiveData. If the request fails -> it is repeated after 1, 2, 4, 8 (*2..) seconds. This funtion is work, but i want to write a Spek test to test this code (for teaching purposes), right now it looks like this:

@OptIn(ExperimentalCoroutinesApi::class, DelicateCoroutinesApi::class)
object DefaultCoroutinesViewModelTest : Spek({

    val viewModel by memoized { DefaultCoroutinesViewModel() }
    val retrofitService by memoized { mock<RetrofitService>() }

    describe("get character") {

        val id = Random.nextInt()
        val response = mock<Response<RickAndMortyCharacter>>()

        beforeEachTest {
            Dispatchers.setMain(newSingleThreadContext("Test thread"))
            runTest {
                launch(Dispatchers.Main) {
                    given(retrofitService.getDataFromApi(id)).willReturn(response)
                }
            }

            viewModel.getCharacter(id)
        }

        it("must get data from API") {
            runTest {
                launch(Dispatchers.Main) {
                    verify(retrofitService).getDataFromApi(id)
                }
            }
        }
    }
})

But now, when i start this test - i get error: Wanted but not invoked: retrofitService.getDataFromApi(511291517);. what am I doing wrong that the retrofitService.getDataFromApi() is not called during the test?

My viewModel.kt

private const val DEFAULT_REQUEST_DELAY = 1000L

class DefaultCoroutinesViewModel : CoroutinesViewModel() {

    override val characterLiveData = MutableLiveData<RickAndMortyCharacter>()

    private var requestTimerMSec = DEFAULT_REQUEST_DELAY

    private val retrofitService: RetrofitService = RetrofitInstance
        .getRetroInstance()
        .create(RetrofitService::class.java)

    override fun getCharacter(id: Int) {
        viewModelScope.launch(Dispatchers.Main) {
            val requestResult = kotlin.runCatching {
                retrofitService.getDataFromApi(id) }
            requestResult.onSuccess {
                AppLogger.d("Successful request: character ${it.body()?.name}")
                characterLiveData.value = it.body()
            }.onFailure {
                AppLogger.e("New request after ${(requestTimerMSec / DEFAULT_REQUEST_DELAY).toInt()} sec delay")
                delay(requestTimerMSec)
                requestTimerMSec *= 2
                getCharacter(id)
            }
        }
    }
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source