You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Android中如何优雅Mock ApolloClient的Query响应以测试方法

优雅Mock ApolloClient Query响应的方案

针对你在测试myMethod时遇到的Mock ApolloClient响应的问题,我有几个贴合需求的优雅方案,不需要依赖MockWebServer,也不用Mock整个Rx2Apollo.from环节:

方案一:自定义极简MockApolloCall + Mockito

我们可以自己实现一个轻量的MockApolloCall,它能预设成功响应或错误,再用Mockito让ApolloClient返回这个Call实例,完美适配Rx2Apollo的转换逻辑。

步骤1:实现MockApolloCall

class MockApolloCall<T>(
    private val response: ApolloResponse<T>? = null,
    private val error: Throwable? = null
) : ApolloCall<T>() {

    override fun clone(): ApolloCall<T> = this

    override fun execute(): ApolloResponse<T> {
        error?.let { throw it }
        return response ?: throw IllegalStateException("Either response or error must be provided")
    }

    override fun enqueue(callback: ApolloCall.Callback<T>) {
        try {
            error?.let { callback.onFailure(it) } ?: response?.let { callback.onResponse(it) }
        } catch (t: Throwable) {
            callback.onFailure(t)
        }
    }

    override fun cancel() {}
    override fun isCanceled(): Boolean = false
}

这个类实现了ApolloCall的核心方法,Rx2Apollo会调用enqueue方法转换为Observable,所以我们只需要在这个方法里触发预设的成功/失败回调即可。

步骤2:在测试中Mock ApolloClient

假设你用Mockito做Mock框架,测试代码可以这样写:

// 初始化Mock的ApolloClient
val mockApolloClient = mock(ApolloClient::class.java)

// 构建你需要的测试数据
val mockEntities = listOf(MyEntity(id = "1"), MyEntity(id = "2"))
// 构建符合Query返回结构的ApolloResponse
val mockResponse = ApolloResponse.builder<YourQuery.Data>()
    .data(YourQuery.Data(mockEntities)) // 替换为你的Query对应的Data对象
    .build()

// 让ApolloClient的query方法返回我们的MockApolloCall
`when`(mockApolloClient.query(any<Query>())).thenReturn(MockApolloCall(mockResponse))

// 注入mockApolloClient到目标类,调用myMethod验证结果
val result = yourClass.myMethod("testId").blockingGet()
assertEquals(mockEntities, result)

如果要测试错误场景,只需要传入error参数:

`when`(mockApolloClient.query(any<Query>())).thenReturn(MockApolloCall(error = IOException("Mock network error")))

val result = yourClass.myMethod("testId").blockingGet()
assertTrue(result.isEmpty())

方案二:利用Apollo Android内置测试工具类

Apollo Android提供了官方的测试辅助类TestApolloCall,在apollo-testing-support依赖中,能帮我们省去自己实现MockCall的麻烦:

首先添加测试依赖:

testImplementation "com.apollographql.apollo:apollo-testing-support:x.y.z" // 替换为你的Apollo版本

然后测试中可以直接用:

val mockEntities = listOf(MyEntity(id = "1"), MyEntity(id = "2"))
val mockResponse = ApolloResponse.builder<YourQuery.Data>()
    .data(YourQuery.Data(mockEntities))
    .build()

// 创建成功响应的TestApolloCall
val testCall = TestApolloCall.success(mockResponse)
`when`(mockApolloClient.query(any<Query>())).thenReturn(testCall)

// 后续测试逻辑和方案一一致

模拟错误场景则用:

val testCall = TestApolloCall.failure(IOException("Mock error"))
`when`(mockApolloClient.query(any<Query>())).thenReturn(testCall)

方案优势

  • 完全避开MockWebServer和Rx2Apollo.from环节的Mock,专注测试myMethod的核心逻辑
  • 可以精准控制返回的响应或错误,覆盖所有测试场景
  • 代码简洁复用性强,不管是成功还是错误场景都能轻松处理

内容的提问来源于stack exchange,提问作者Alejandra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 10:22:59