Mock GraphQL queries with Cypress and TestCafe

Do you think mocking your GraphQL backend is always a tedious task? Fasten your seat belts, I am gonna change your mind.

Mocking is the practice of creating a fake version of a component so that you can develop and test other parts of your application independently. The strongly-typed nature of a GraphQL API lends itself extremely well to mocking. This is an important part of a GraphQL-First development process.

Mocking backends has been hard due to the traditional reason: there is no standard REST API description in machine-consumable format. But, GraphQL makes mocking easy, because every GraphQL backend comes with a static type system. The types can be shared between your backend and your frontend, and they contain all of the information necessary to make mocking incredibly fast and convenient. With GraphQL, there is no excuse to not mock your backend for development or testing.

Cypress.io and Testcafe both are exceptional next-generation E2E testing tools. Both the tools provide fluent commands to create stubs and mock HTTP requests quite easily. But, taking about GraphQL queries, things are not that straight forward.

Before we proceed further, I have created a sample graphql-mock-example repository loaded with Client app, cypress, and Testcafe examples. You will find heavy references to that repository.

The GraphQL magic

Let’s take a look, how we can mock a GraphQL schema with just one line of code, using the default mocking logic you get out of the box with graphql-tools.

Every GraphQL server needs a schema. And the query is the one your component already uses for fetching data, so that’s also not code you write just for mocking.

Put that in contrast to most REST APIs out there, where mocking means parsing a URL and returning data in a custom shape for each endpoint. It takes dozens of lines to mock a single endpoint that returns some realistic-looking data. With GraphQL, the shape is encoded in the query, and together with the schema, we have enough information to mock the server with a single line of code.

But, this will not natively help you mocking data in your end-to-end tests. Cypress and Testcafe mostly works in a browser context. So, you need to develop stubbing mechanism to process the mock data and set the response accordingly.

Quick look into our AUT

We have React in the front-end. We are using Apollo for the state management between React and GraphQL. Application is trualy a simple one. It is having a button, on clicking it shows user data in JSON format. Just remember the query that is getting fired from the UI. Later you will be putting that into specific GraphQL schema management file which we will be reading from our test tools — Cypress and TestCafe.

How to mock with Cypress

Ninjas, who already familiarized with Cypress, know how to mock HTTP API calls with cy.route() command. But, that will not work in case of GraphQL queries. The trick to mocking GraphQL in Cypress is by creating a stub for window.fetch

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.

Now, you don’t need to create these stubs on your own. You can make use of an awesome library called cypress-graphql-mock

Install the library as a dev-dependency:

npm i -D cypress-graphql-mock@0.3.1

Most often you will be creating GraphQL schema language in a .graphql file or .gql file. cypress-graphql-mock library needs to load the schema definition file. Cypress cant read files inside a test as it will be running on browser context. You need to create a Task to read the schema file.

This task should be created cypress/plugin/index.js

This task helps you to execute Node specific code before cypress loads the browser. This piece of event you need to execute via cy.task() inside your test code.

Now, you finished loading the GraphQL schema in your test. Now, its time to set the mock data on a specific query

As the library mocked the window.fetch calls and uses graphql’s internal mocking capabilities, in runtime, it will validate the query fired by the UI and respond back with the mock data.

So, your complete test will look like:

Have a look into these sample tests to understand different mocking capabilities. 

How to mock with TestCafe

TestCafe on the other hand has an inbuilt mocker that can intercept requests to this resource and emulate the response as needed. There is an easy to use library called testcafe-graphql-mock that internally handles the mocking mechanism and enhance TestCafe’s in house RequestMock capabilities. So, if you are familiar with TestCafe’s mocking mechanism, this will be a child’s play.

Install the library as Dev-Dependency

npm i -D testcafe-graphql-mock

One of the benefits that TestCafe provides is the capability of running Node operation on the go. So, unlike cypress, you no need to add an extra task to read the graphql file. You can create a RequestMock object like below:

The way the mock object is defined is again different than the Cypress operation. It allows you to specify functions that are called for specific types in the schema. Schema to mock mapping thus pretty easy here.

Now, you need to use requestHooks (Again TestCafe in-house capability) to attach the RequestMock in fixture or in test . Testcafe will internally handle the rest. So, your final test will look like:

Pretty clean right?

Have a look into these sample tests to understand different mocking capabilities with testcafe.

Final Words + Try It Yourself

mocking is fun. Moreover, it accelerates the speed of development in the team. Both the tools are excellent while it comes to mock GraphQL queries. In the end, it’s the call of circumstances and use cases. While Cypress allows you to more flexible with custom codes, another hand, TestCafe internally offers APIs to handle the mocking and allows you to be more structured. My intention is not to suggest a tool over others as internally both extend the graphql-tool capabilities. I leave you in your thoughts here.

I am providing this sample respositoty, try things out.

Happy coding….

Ah, in case you love the article, leave some precious claps ^^

Software Engineer @Postman 🚀 | Space Movie Lover 🪐 | Coder 👨‍💻 | Mountain Trekker⛰️