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
相关产品推荐
相关产品推荐

