0

I am trying to perform a unit test and mock a retrofit call without success. When I run my test, I get only end printed. I should receive onResponse() printed as well.

The code works fine when I run my app, only the test does not call the mocked API call.

Method in ViewModel:

fun loadSensors() {
    CoroutineScope(Dispatchers.IO).launch {
        sensorsService.getUserSensors(getUserToken(), getUserId())
            .enqueue(object : Callback<List<Long>> {
                override fun onResponse(
                    call: Call<List<Long>>,
                    response: Response<List<Long>>
                ) {
                    println("onResponse()")
                }

                override fun onFailure(call: Call<List<Long>>, t: Throwable) {
                    println("onFailure()")
                }
            })
    }
    println("end")
}

Interface:

@GET("/sensors")
fun getUserSensors(): Call<List<Long>>

App module:

@Provides
@Singleton
fun provideRetrofitFactory(gsonConverterFactory: GsonConverterFactory): Retrofit {
    val client = OkHttpClient.Builder().build()

    return Retrofit.Builder()
        .baseUrl("http://<url>")
        .addConverterFactory(gsonConverterFactory)
        .client(client)
        .build()
}

Test:

@OptIn(DelicateCoroutinesApi::class)
private val mainThreadSurrogate = newSingleThreadContext("UI thread")

@OptIn(ExperimentalCoroutinesApi::class)
@BeforeAll
fun beforeAll() {
    Dispatchers.setMain(mainThreadSurrogate)
}

@Test
fun loadSensors() {
    val mockedCall = mockk<retrofit2.Call<List<Long>>>()
    every { mockedCall.enqueue(any()) } answers {
        val callback = args[0] as retrofit2.Callback<List<Long>>
        val response = retrofit2.Response.success(200, listOf(1L, 2L, 3L))

        callback.onResponse(mockedCall, response)
    }

    every { sensorsService.getUserSensors(any(), any()) } answers {
        mockedCall
    }
}
Captain Jacky
  • 888
  • 1
  • 12
  • 26
  • you can follow something like this to get the connection using MockWebServer: https://proandroiddev.com/testing-retrofit-converter-with-mock-webserver-50f3e1f54013 – Yonatan Karp-Rudin Nov 20 '22 at 16:15
  • Hi, I've tried something else, because I can't get `MockWebServer` and `Coroutines` work together. There's is also an unsolved thread: https://stackoverflow.com/questions/71489875/how-to-make-mockwebserver-retrofit-coroutines-run-in-the-same-dispatcher – Captain Jacky Nov 21 '22 at 14:21

1 Answers1

0

I recommended that you see MockWebServer I am sure with use it you can do anything you have in your mind.

Erfan Sn
  • 89
  • 1
  • 6