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()
andtext()
) and a property (ok
) that indicates whether the request was successful (returns a HTTP 2xx/3xx). We stub this with theresponseStub
. - 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 ifwindow.fetch
already was stubbed earlier. If it wasn’t, it’s stubbed withcy.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 acallsFake
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 thefetchGraphQL
function. - The
fetchGraphQL
mock function extracts the operationName from the body and calls thegetOperationMock
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!