Mocking specific GraphQL requests in Cypress.io

At Wehkamp, we build our front-end with React and GraphQL, which is a beautiful stack to work in. For a new project, I took it upon myself to write the end-to-end tests in Cypress.io, another tool that I love to work with.

In this project, the user goes through a flow that involves a third party for identification that looks like this.

Because we don’t want to test this part (that’s the job of the third party, right?), we need to mock the call from the browser in Cypress. However, because we use GraphQL, we can’t just use the cy.route command. The trick to mocking GraphQL in Cypress is by creating a stub for window.fetch.

This can be done like this:

The way it works is like this:

  • The Fetch API returns a promise which resolves to an object with two methods (json()and text()) and a property (ok) that indicates whether the request was successful (returns a HTTP 2xx/3xx). We stub this with the responseStub.
  • The isStub method is used to check if a method already has been stubbed. This becomes useful in the next function :).
  • The getFetchStub first checks if window.fetch already was stubbed earlier. If it wasn’t, it’s stubbed with cy.stub. The original fetch method is stored in a variable, so it can be called when there’s no mocked implementation for a GraphQL call. Then finally, the stub is extended with a callsFake handler.
  • Then finally, a custom Cypress command is added. It takes a function that takes an operationName and returns an object with a test function and a result object. The actual command only adds the fetch stub which calls the fetchGraphQL function.
  • The fetchGraphQL mock function extracts the operationName from the body and calls the getOperationMock function. That returns an optional test method (to check if the variables passed to the GraphQL operation are what you expect) and a mockResult. 
    If no mock data for the operation is found, it calls the original fetch API with the same parameters and returns the result.

So how do you actually use this in a test? That is pretty straightforward:

Call the custom command in the beforeEach of your Cypress test, and pass it a function that returns an object for the given operationName. Then just visit your page and do your tests normally.

Thank you for taking the time to reading this story! You can follow me on Twitter @ronderksen and feel free to tweet me anything!

Also, I work at Wehkamp one of the biggest e-commerce companies of the Netherlands. We do have a Tech blog, check it out and subscribe if you want to read more stories like this one. Or look at our job offers if you are looking for a great job!