Later Edit
I ended up to have my api service methods suspended
and refactor my code as suggested by @LordRaydenMK.
The reason for using the library ru.gildor.coroutines:kotlin-coroutines-retrofit
it the first place was out of pure convenience AND it was before retrofit released the version which would support for coroutines.
Original Question
I have been trying for a couple of days to mock the API calls with no success. I'm using the following libraries:
retrofit
- i think we are all familiar with itru.gildor.coroutines:kotlin-coroutines-retrofit
- for a couple of useful coroutine extensionsio.mockk:mockk
- for mocking
It is a simple case of mocking the API response
interface ApiService {
@GET
fun getMyData(@Header("x-value") myValue: String): Call<String>
}
class Usecase(api: ApiService) {
suspend fun execute() {
val result = api.getMyData(value: String).awaitResult()
// do smth with that result for now just return it
return (result as Result.Ok).value
}
}
class UseCaseTest {
private val api = mockk<ApiService>()
@Test
fun testApiCall() {
coEvery { api.getMyData(any()) } returns CallTest.buildSuccess("you did it!")
val result = useCase.execute()
assertEquals(result, "you did it!")
}
}
In the example above the test hangs on the awaitResult extension method.
What i have tried so far with no luck:
- mockkStatic(ru.gildor.coroutines.retrofit.CallAwait) but with no success
- mockk
Call<String>
and do acoEvery { mockedCall.awaitResult() } returns ....
I'm sure it's something simple that I'm missing and a pair of fresh eyes will spot it from a mile away.
CodePudding user response:
First thing:
getMyData
is NOT a suspend
function so probably you should NOT be using coEvery
when mocking it (tho I'm not a Mockk user).
That being said, Retrofit does support suspend
functions natively, so you could do:
interface ApiService {
@GET
suspend fun getMyData(@Header("x-value") myValue: String): String
}
that means no need for awaitResult
in your use case. In this scenario you do need coEvery
when mocking it.