Testing Apollo React with Cypress

Mock multiple GraphQL calls with the same endpoint using Cypress

As a team we stumbled upon a challenge while using Cypress to test our React Apollo GraphQL application. We needed to make multiple mock calls to the endpoint /grahpql with only our GraphQL query as the main difference. At the moment of writing this post, Cypress does not have a solution for this that works out of the box.

Base setup

We started off the application to write tests for our frontpage. We instruct Cypress to navigate to the frontpage before each test and get the config for our site, we used the beforeEach function for this.

Mock GraphQL call

A small hack is used that sets the win.fetch to null so we are able to mock the responses. Apollo uses win.fetch internally to get responses from the server, we don’t want Apollo to to do that.

How this actually works is that every time Apollo, in our React application, makes a call to /graphql Cypress will hijack this call and return the content of site_config.json as response. This is perfect so far.

Multiple calls

The problem arose when we needed to mock the content of the page, which also is just a post call to /graphql, but with a different query. We tried something like this:

Wrong way of mocking multiple GraphQL calls

Cypress only returns the response from the first JSON file, and the second response is never fired. Rage!

Github to the rescue!

We searched Github for a solution and stumbled upon the following issue which proposed a solution for stubbing GraphQL calls using Cypress. As my teammate already explained as a response to the issue we had to fiddle around with it a little but got it working in the end.

Now in the beforeEach of our test we can use the following.

This made it possible to mock the complete page, with all the calls going to /graphql but all getting their own mock data.

End note

Surely it won’t take long before Cypress will come up with a good solution for this, so be sure to keep an eye out for something more simple. Until that solution is available, this one works for the time being.