Mocking GraphQL responses


The test network transports are currently experimental in Apollo Kotlin. If you have feedback on them, please let us know via GitHub issues or in the Kotlin Slack community.

QueueTestNetworkTransport is a high-level test API that lets you specify the GraphQL responses that are returned by your ApolloClient instance.

Add the dependency to your project's build.gradle file:

Kotlin
build.gradle[.kts]
1dependencies {
2  testImplementation("com.apollographql.apollo:apollo-testing-support:4.1.0")
3}

Enable the QueueTestNetworkTransport by passing it to the ApolloClient builder:

Kotlin
1val apolloClient = ApolloClient.Builder()
2    .networkTransport(QueueTestNetworkTransport())
3    .build()

You can then use the enqueueTestResponse extension function to specify the GraphQL responses to return:

Kotlin
1val testQuery = GetHeroQuery("001")
2val testData = GetHeroQuery.Data {
3  hero = droidHero {
4    name = "R2D2"
5  }
6}
7apolloClient.enqueueTestResponse(testQuery, testData)
8
9val actual = apolloClient.query(testQuery).execute().data!!
10assertEquals(testData.hero.name, actual.hero.name)

You can pass an ApolloResponse to the enqueueTestResponse function, or as a shortcut, you can pass a Data directly as shown above. If you do pass a Data, you also need to pass an operation, because an ApolloResponse is built under the hood, which needs a reference to it.

To help create your mocked response data, you can use data builders.

Advanced usage

QueueTestNetworkTransport returns responses in the order they've been enqueued.

In certain tests, it might be more convenient to map responses to operations.

To achieve this, use MapTestNetworkTransport instead and call the registerTestResponse extension function:

Kotlin
1val apolloClient = ApolloClient.Builder().networkTransport(MapTestNetworkTransport()).build()
2
3apolloClient.registerTestResponse(query1, testData1)
4apolloClient.registerTestResponse(query2, testData2)
5
6val actual1 = apolloClient.query(query1).execute().data
7val actual2 = apolloClient.query(query2).execute().data
8// Execute query1 again, which is mapped to testData1
9val actual3 = apolloClient.query(query1).execute().data
10
11assertEquals(testData1, actual1)
12assertEquals(testData2, actual2)
13assertEquals(testData1, actual3)

If you need more control over the responses to return, you can implement your own NetworkTransport and pass it to the ApolloClient builder:

Kotlin
1private class CustomTestNetworkTransport : NetworkTransport {
2  override fun <D : Operation.Data> execute(request: ApolloRequest<D>): Flow<ApolloResponse<D>> {
3    return flowOf(
4        ApolloResponse.Builder(
5          /* Your custom logic here */
6        ).build() as ApolloResponse<D>
7    )
8  }
9
10override fun dispose() {}
11}
12
13apolloClient = ApolloClient.Builder()
14    .networkTransport(CustomTestNetworkTransport())
15    .build()

Note that if you use a custom NetworkTransport, calling enqueueTestResponse() or registerTestResponse() is no longer possible because they expect the transport to be QueueTestNetworkTransport or MapTestNetworkTransport.

Feedback

Edit on GitHub

Forums