As of this writing, there is no official testing guide for react-apollo. But there are a number of unofficial blog posts and articles. Here’s a sample:

So why write another blog post? Well, after a lot of spelunking, I came to the conclusion that most react-apollo developers approach tests in one of two ways:

• They test their components with a mocked version of apollo
• They separate apollo-related code from their components into containers, and only test the non-apollo components

After experimenting with both methods, I discovered a nice way to integrate these approaches. Others may have already done this, but I haven’t seen it explicitly articulated anywhere.

The key is to split tests into two types:

• Tests that verify a component behaves correctly given certain props (component tests)
• Tests that verify a container passes down the right props given certain mocked global state (container tests)

## Sketching out the specs

Let’s try this on a real world example. Consider a ToDo application that allows a user to nest ToDos via a single input at the bottom of the screen. Here’s a gif of the behavior we want:

We’ll focus on the component at the bottom (the piece with the green background), which we’ll call <TaskCreator/>. We’ll keep all of the data queries and mutations in a separate container called <TaskCreatorContainer/>, and pass the data and mutations to <TaskCreator/> via props.

Now lets sketch out how we want our component and our container to behave via some unimplemented specs:

Component Specs

Source

Container Specs

Source

## Implementing the specs

The first set of tests should be straighforward to anyone who’s tested react components, so we won’t go into them here. If you’re new to testing react components, I highly recommend getting comfortable with enzyme and implementing some regular, non-container tests before proceeding.

The second set of tests is trickier. The basic idea is to test that a component receives a certain set of props given a certain global state, which includes things like apollo query results, redux state, and react-router state.

This sounds sort of like an integration test that we could implement with selenium. But if we look at what containers actually are, we see that they’re just react components that query/mutate data. Selenium tests are better suited for final user flows once we want to test a bunch of containers and APIs interacting with each other. If we want to test the API of a single container, we’ll want to test a bunch of different inputs to that API, which would be difficult and slow to do via something like selenium.

In order to test how our container responds to different global state, we’ll need to mock it out. The <MockedProvider /> component inside of react-apollo is close to what we want, but we’ll need something that mocks out all of the global state relevant to our containers, not just apollo. Let’s call this hypothetical component <TestProvider/>. Here’s how we’d use it:

Source
NOTE: def is like rspec’s let, and sets the \$ variables. Comes from bdd-lazy-var.

To mock out graphql responses for apollo 2.0, we’ll use apollo-schema-link. This allows us to hit the schema directly without any network requests. Then we will use addMockFunctionsToSchema from graphql-tools to mock out our resolvers. Both libraries are well documented and officially supported by apollo. Here’s how we’ll use them in <TestProvider/>:

Source

Now let’s add some methods to mock out redux state and record actions:

Source

Depending on what you’re using for global state and what your containers look like, you might have some more methods in your <TestProvider/>. In our case, all we care about is redux and apollo, so we’re ready to use our <TestProvider/> in our container specs:

Source

We now have implemented container specs. Hooray!

## What we gained

So why’d we do all that?

We can now confidently refactor GraphQL queries/fragments

• If we change a shared query or fragment, our tests ensure each dependent component is still getting the props it needs

We can now confidently refactor redux actions/reducers

• If we change an action/reducer, our tests ensure that the props which are supposed to mutate redux are still having the intended effect

We can now confidently refactor shared hocs

• If we change a shared hoc, our tests ensure each dependent component still gets the props it needs

We can now confidently refactor our schema

• If we change the schema and make a query invalid, our tests will complain instead of giving us false positives

We don’t need to know so much about apollo anymore

• If apollo changes their API (by changing/removing ‘loading’ from the data prop, for example), our tests will complain instead of giving us false positives
• If apollo changes how it parses errors, we won’t need to change our tests, since we’re throwing the same errors we’re expecting to be thrown in the resolvers.

We now can hook our component up to other data sources without rewriting tests

• If we want to use our component in some other context (maybe with a different query, or hydrated by something other than apollo), our component tests our still valid.