【问题标题】:Mock API calls with Retrofit + coroutines + Mockk使用 Retrofit + coroutines + Mockk 模拟 API 调用
【发布时间】:2022-02-18 01:58:56
【问题描述】:

稍后编辑

我最终得到了我的 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) 但没有成功
  • 模拟Call&lt;String&gt; 并做一个coEvery { mockedCall.awaitResult() } returns ....

我确信我错过了一些简单的东西,一双新鲜的眼睛会在一英里外发现它。

【问题讨论】:

    标签: unit-testing kotlin kotlin-coroutines mockk


    【解决方案1】:

    第一件事:

    getMyData 不是 suspend 函数,所以在模拟它时可能不应该使用 coEvery(虽然我不是 Mockk 用户)。

    话虽如此,Retrofit 本身确实支持 suspend 函数,所以你可以这样做:

    interface ApiService {
    
      @GET
      suspend fun getMyData(@Header("x-value") myValue: String): String
    }
    

    这意味着在您的用例中不需要awaitResult。在这种情况下,您在模拟时确实需要 coEvery

    【讨论】:

    • 公平点,getMyData 可以与 every 功能一起消失,但这并没有改变很多事情。关于在 ApiService 挂起中使用,这是一个想法,但这意味着要大规模更改代码库。
    • 您是否尝试将getMyData 转换为suspend?我的理论是在假/模拟对象上调用 awaitResult() 可能有问题。这将消除对它的需求。
    • 我做了,但是更改会级联到实际实现中的更改的兔子洞。在调试期间awaitResult 的模拟对象肯定有问题,结果从 apiService 正确返回,然后挂到awaitResult
    • 我最终切换并暂停了我的 api 服务方法并重构了我的代码。使用库ru.gildor.coroutines:kotlin-coroutines-retrofit 的原因纯粹是为了方便,而且是在改造发布支持协程的版本之前。我会将您的答案标记为已接受
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 2019-03-15
    • 1970-01-01
    相关资源
    最近更新 更多