使用 Retrofit + 协程 + Mockk 模拟 API 调用
Mock API calls with Retrofit + coroutines + Mockk
稍后编辑
我最终得到了我的 api 服务方法 suspended
并按照@LordRaydenMK 的建议重构了我的代码。
使用该库的原因 ru.gildor.coroutines:kotlin-coroutines-retrofit
它首先是出于纯粹的方便 并且 它是在 retrofit 发布支持协程的版本之前。
原题
几天来我一直在尝试模拟 API 调用,但没有成功。我正在使用以下库:
retrofit
- 想必大家都很熟悉吧
ru.gildor.coroutines:kotlin-coroutines-retrofit
- 一些有用的协程扩展
io.mockk:mockk
- 用于模拟
这是一个模拟API响应的简单案例
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!")
}
}
在上面的示例中,测试在 awaitResult 扩展方法上挂起。
到目前为止我已经尝试过但没有成功:
- mockkStatic(ru.gildor.coroutines.retrofit.CallAwait) 但没有成功
- mockk
Call<String>
然后做一个 coEvery { mockedCall.awaitResult() } returns ....
我敢肯定这很简单,我错过了,一双新鲜的眼睛会在一英里外发现它。
第一件事:
getMyData
不是 suspend
函数,所以你可能不应该在模拟它时使用 coEvery
(虽然我不是 Mockk 用户)。
话虽这么说,Retrofit 本身就支持 suspend
函数,所以你可以这样做:
interface ApiService {
@GET
suspend fun getMyData(@Header("x-value") myValue: String): String
}
这意味着在您的用例中不需要 awaitResult
。在这种情况下,您在模拟它时确实需要 coEvery
。
稍后编辑
我最终得到了我的 api 服务方法 suspended
并按照@LordRaydenMK 的建议重构了我的代码。
使用该库的原因 ru.gildor.coroutines:kotlin-coroutines-retrofit
它首先是出于纯粹的方便 并且 它是在 retrofit 发布支持协程的版本之前。
原题
几天来我一直在尝试模拟 API 调用,但没有成功。我正在使用以下库:
retrofit
- 想必大家都很熟悉吧ru.gildor.coroutines:kotlin-coroutines-retrofit
- 一些有用的协程扩展io.mockk:mockk
- 用于模拟
这是一个模拟API响应的简单案例
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!")
}
}
在上面的示例中,测试在 awaitResult 扩展方法上挂起。
到目前为止我已经尝试过但没有成功:
- mockkStatic(ru.gildor.coroutines.retrofit.CallAwait) 但没有成功
- mockk
Call<String>
然后做一个coEvery { mockedCall.awaitResult() } returns ....
我敢肯定这很简单,我错过了,一双新鲜的眼睛会在一英里外发现它。
第一件事:
getMyData
不是 suspend
函数,所以你可能不应该在模拟它时使用 coEvery
(虽然我不是 Mockk 用户)。
话虽这么说,Retrofit 本身就支持 suspend
函数,所以你可以这样做:
interface ApiService {
@GET
suspend fun getMyData(@Header("x-value") myValue: String): String
}
这意味着在您的用例中不需要 awaitResult
。在这种情况下,您在模拟它时确实需要 coEvery
。