Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TestNetworkTransport #3737

Closed
martinbonnin opened this issue Dec 16, 2021 · 2 comments
Closed

TestNetworkTransport #3737

martinbonnin opened this issue Dec 16, 2021 · 2 comments

Comments

@martinbonnin
Copy link
Contributor

martinbonnin commented Dec 16, 2021

Now that we have test builders, we can use them to make writing tests easier. The testing can happen at 2 levels:

  1. HTTP
  2. GraphQL (this issue)

The NetworkTransport interface is relatively simple:

interface NetworkTransport {

  fun <D : Operation.Data> execute(
      request: ApolloRequest<D>,
  ): Flow<ApolloResponse<D>>

  fun dispose()
}

TestNetworkTransport can maintain a MutableMap<Operation, ApolloResponse> so that it responds with the pre-recorded ApolloResponse for the given operation (that would be build from the test builders).

Building a test client:

val testApolloClient = ApolloClient.Builder()
       .networkTransport(TestNetworkTransport())
       .build()

Ideally, the API would look like:

val testNetworkTransport = testApolloClient.testNetworkTransport // this is an extension function that throws if the networkTransport is not a TestNetworkTransport

val query = HeroQuery()
testNetworkTransport.registerResponse(query) {
  hero = humanHero {
    name = "Luke"
  }
}

// Use it
testApolloClient.query(query).execute().data?.hero?.name 
// "Luke" 

The registerOperation {} part is the hard part because there's no simple generic way to get the HeroQuery_TestBuilder from a HeroQuery reified type parameter. We might be able to use some compiler plugin magic like kotlinx.serialization but that adds a new component into the equation.

Another solution might be to have a global registry of _TestBuilder keyed by KClass but even there I'm not sure how to retrieve them without reflection, which sounds like it's doable on the JVM but not always desired and not possible at all on MPP

@BoD
Copy link
Contributor

BoD commented Dec 17, 2021

Just a thought: for the logic returning the ApolloResponse, in addition to a "map oriented" API it may be useful to also have a "queue oriented" one and/or one where you can pass a lambda for custom logic. (I'm thinking about a test scenario where the same query executed twice returns different responses). Something like:

var count = 0
testNetworkTransport.register(query) { query ->
  count++
  when (count) {
    1 -> {
      hero = humanHero {
        name = "Luke"
      }
    }
    2 -> {
      hero = humanHero {
        name = "Han"
      }
   }
}

@martinbonnin
Copy link
Contributor Author

Fixed in 3.1.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants