Auto-mocking using Cypress
Tags: webdev, cypress, productivity, javascript
Published: 2021-10-11 21:37:54

Someone great once said 
> Never do it manually when you can automate it. 

Recently I am on the lookout for automating things that I am doing repetitively during web development. 

And one of the things I found is the creation of mock data in a local environment. Anyone doing web development knows that for a frontend-facing application there are numerous conditions, logic, and error scenarios, for which you need to test it on a local development environment before shipping to production. 

For this, a developer usually replicates the data that the app consumes from a production environment to a local environment often known as mock data. There are several ways of serving mock data in a local host server, for example using a node server like [express](https://expressjs.com) or a library like [mockAPI](https://mockapi.io/docs). Either way one needs to have many local JSON files that need to be served in place of the response data coming from the API request. 

I usually create a new JSON file in a folder, copy-paste the data from a network response from a browser dev tool or a postman, and I am guessing that this is what most developers do. This can be cumbersome when there are several logical scenarios and each scenario involves several requests with unique data.

So let me jump right into my solution. For this I am using an awesome end-to-end testing library called [cypress.io](https://www.cypress.io), combined with [Cucumber](https://cucumber.io) scenarios using Gherkin syntax. Please refer the documentation if you are new to Cypress as I will not be going through the basics. 

I used [cypress-cucumber-preprocessor] (https://github.com/TheBrainFamily/cypress-cucumber-preprocessor) library to integrate Cucumber into Cypress testing.

```
"cypress": "^x.x.x",
"cypress-cucumber-preprocessor": "^x.x.x"
```

Once you have the above packages installed, you will be having a similar folder structure like below:
![Cypress tests folder structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ax6rcim8y3bzkfk8qexy.png)

A feature file, say `Updatemock.feature` is to be created in the integrations folder with the Cucumber scenario with the automation steps that will trigger the API requests that need mocking. 

For example if you want to mock the api requests that happens after a search term is searched you would write something like this:

```
Feature: Update the mocks in mock-server folder from production environment

  Background:
    Given I login from login page
    Then I see the app

  @updatemock
  Scenario Outline: Update mock data
    When I intercept api network request
    When I input "<SearchTerm>" in Search Input field
    And I click Submit button
    Then the web search results mock data is updated
    Then the Image search results mock data is updated
    Examples:
      | SearchTerm |
      | Tesla |
      | Beyonce|   
```

Then the steps are implemented in a javascript file. I have shown below the 2 main steps that does the trick. 

```
Given(/^I intercept api network request$/, function() {
  cy.intercept("https://api.dooble.com/search?**").as(
    "search"
  );
});

Then(/^the web search results mock data are updated$/, function() {
  try {
    cy.wait("@search").then(res => {
     const query = res.response.url.split("?");
     const urlParams = new URLSearchParams(query[1]);
     const searchTerm =  urlParams.get("search");
     cy.writeFile(`mock-server/mock-data/${searchTerm}.json`,      res.response.body);
    });
  } catch (e) {
    cy.log(e);
  }
});
```
```
cypress open //headful mode
cypress run  //headless mode
```
On running the feature file using the cypress command on a production environment the steps described in the cucumber scenario are recreated in a headless or headful browser depending on the mode you run in. The `cy.intercept()` function spy the request which can be later awaited using a `cy.wait()` command and the response is then written to the file path of the mock data. 

That’s it! This scenario can be run on `n` number of data in a single run and multiple requests can be intercepted to write mock data files within seconds (or minutes depending on the network response). I believe any e2e testing tool can achieve the same, like puppeteer, playwright or Codecept. I used cypress as it is the tool that I use in my project for testing. 

This approach has saved a lot of time for me, and I hope it will for you too.