JavaScript API Mocking Techniques

Suresh Mohan - Sep 15 '22 - - Dev Community

API mocking plays a significant role in the software development process. It allows developers to simulate the actual APIs and receive realistic responses generated with custom data. For example, you can use mock APIs when writing unit tests or situations where external dependencies are unavailable to make things easier.

In this article, I will discuss what API mocking is, why we need it, and what different API mocking techniques we can use in JavaScript.

What is API Mocking?

API mocking is a process in which developers imitate the actual APIs with mock APIs. These mock APIs behave similarly to the actual APIs and perform the basic functionality required to develop or test.

For example, there may be dependencies with external APIs that are unavailable in the developer environment. In such instances, you can use mock APIs to continue the development uninterrupted until the actual external APIs come live.

In addition, there are instances where the developers need to implement and test the front end first or when two different development teams develop the front end and back end separately. In such cases, it is always better to check whether the front end is properly functioning even when the actual back end is not available. We can use API mocking to test and confirm that the front end functions properly.

Why Use Mock APIs?

  • They help to mock data when writing unit tests without calling the live API.
  • The whole development speeds up as the front-end and back-end developers can work parallelly.
  • They help carry out offline development.
  • They can speed up the development process if the real APIs are slow.
  • The front end can act as a standalone application without back-end dependencies in the development phase.

JavaScript Libraries for API Mocking

There are multiple JavaScript libraries available for API mocking. Selecting a suitable library is the first step. Here are some of the most used JavaScript API mocking libraries:

  • JSON Server⁠—A fast and efficient node module that allows creating a REST JSON web service quickly.
  • MirageJS⁠—This is an API mocking library for building, testing, and sharing JavaScript applications independent of back-end services.
  • Nock⁠—An HTTP server mocking library ideal for testing front-end components by making HTTP requests.
  • Axios-mock-adapter⁠—A JavaScript library for sending HTTP requests to APIs.
  • Faker—This is a famous library for generating fake data for testing.

JavaScript API Mocking Techniques: Examples

Now that you have a clear understanding of what API mocking is and why we need it, let’s see how we can create mock APIs using some of the aforementioned libraries.

Mock APIs for JavaScript apps with JSON server

We can use JSON Server to create demo REST APIs in minutes. JSON Server is a node module that allows the mocking of a REST API service with minimum configuration. JSON Server is one of the most popular choices for API mocking because of its efficiency and simplicity.

JSON Server also supports basic validations like responding with 400 if a record of the same ID already exists when creating a new record and 404 if the entity is not there.

Step 1⁠—Installing JSON Server

The first step is to install the JSON Server globally. Then, you can use it for any project when needed.

| npm install -g json-server |

Step 2⁠—Creating the mock data file

Then, create a JSON file with the necessary mock data.

{
  "users": [
    {"id":"1","name": "Nishani", "usertype": "Admin"},
    {"id":"2","name": "Nishani", "usertype": "Manager"},
    {"id":"3","name": "Nishara", "usertype": "Admin"},
    {"id":"4","name": "Nimal", "usertype": "Manager"},
    {"id":"5","name": "Nilantha", "usertype": "Manager"}
  ]
}
Enter fullscreen mode Exit fullscreen mode

Step 3⁠—Starting the server

After that, start the server with the following command.

| json-server --watch users.json --port 8000 |

Step 4⁠—Using in the application

JSON Server supports all GET , POST , PUT , PATCH ,and DELETE request methods. The following code shows how to use the JSON Server for CRUD operations in a React application.

import http from "../http-common";
import axios from "axios";

export default axios.create({
    baseURL: "http://localhost:8000",
    headers: {
        "Content-type": "application/json"
    }
});

export const getAllUsers = () => {
    return http.get("/users");
};
export const getUser = (id) => {
    return http.get(/users/${id} );
};
export const createUser = (data) => {
    return http.post("/users", data);
};
export const updateUsers = (id, data) => {
    return http.put(/users/${id} , data);
};
export const removeUser = (id) => {
    return http.delete(/users/${id} );
};
Enter fullscreen mode Exit fullscreen mode

However, there are several drawbacks to using JSON Server. For instance, JSON Server is not flexible and cannot configure different query parameters for non-CRUD endpoints. Also, you need to set up the test data again if it all gets accidentally deleted, as the JSON Server makes a permanent impact on the data.

Using MirageJS for API Mocking

MirageJS is a client-side mocking framework that mocks the API in the browser by utilizing the Pretender library. It has many built-in tools: serializer, route handlers, database, models, fixtures, and factories. They enable emulating dynamic behavior between the front end and back end, rather than mocking the same response over and over again by hitting an endpoint.

Step 1⁠—Installing MirageJS

MirageJS installation is quite simple with the following command.

| npm install --save-dev miragejs |

Step 2⁠—Edit the server.js file

import { createServer } from 'miragejs';
export function makeServer() {
  let server = createServer();
  return server;
}
Enter fullscreen mode Exit fullscreen mode

The createServer function creates a new mock server instance.

Step 3⁠—Refactor index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import { makeServer } from './server';

if (process.env.NODE_ENV === 'development') {
  makeServer({ environment: 'development' });
} 
ReactDOM.render(
  <React.StrictMode><App /></React.StrictMode>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

The if condition in the previous code is for using the MirageJS server only in the development phase.

Step 4⁠—Using “Model” in MirageJS

Server.js

import { createServer, Model } from 'miragejs';
export function makeServer({ environment = 'test' } = {}) {
  let server = createServer({
    environment,
    models: {
      books: Model,
    },
    seeds(server) {
      server.create('book', {
        title: 'Harry Potter: Philosophers Stone',
        body:
          'The story of a young wizard on his journey to defeat an evil wizard who killed his parents',
      });
      server.create('book', {
        title: 'Lunar Chronicles: Cinder',
        body:
          'A story where the old fairy tales are retold but with an unexpected end',
      });
      server.create('note', {
        title: 'Hunger Games',
        body:
          'The exciting story of Katnis Everdeen in a kill or die game of survival',
      });
    }
});
  return server;
}
Enter fullscreen mode Exit fullscreen mode

Step 5⁠—Creating routes

routes() {

   this.namespace = 'api/books';
   this.get('/', (schema, request) => {
    return schema.books.all();
   });

   this.get('/:id', (schema, request) => {
    let id = request.params.id;
    return schema.books.find(id);
   });

   this.post('/', (schema, request) => {
    let attrs = JSON.parse(request.requestBody);
    return schema.books.create(attrs);
   });

   this.patch('/:id', (schema, request) => {
    let newAttrs = JSON.parse(request.requestBody);
    let id = request.params.id;
    let book = schema.books.find(id);
    return book.update(newAttrs);
   });

   this.delete('/:id', (schema, request) => {
    let id = request.params.id;
    return schema.books.find(id).destroy();
   });

  }
Enter fullscreen mode Exit fullscreen mode
  • GET /api/books⁠ —fetch all book records.
  • GET /api/notes/:id ⁠—fetch a single book record.
  • POST /api/books ⁠—create a new book record.
  • PATCH /api/books/:id ⁠—update an existing book record.
  • DELETE /api/books/:id ⁠—remove an existing book record.

Step 6⁠—Create and configure the front end

The last step is to create or configure the existing front end to get the data created previously using the routes.

A sample output of the previous data follows.

OutputRead more: Mocking Back-ends for React Apps with MirageJS.

Axios-mock-adapter for API Mocking

The Axios-mock-adapter is an NPM library that allows mocking API requests. It is pretty helpful in testing and fron-tend development as this library will enable us to send HTTP requests to an API.

Step 1⁠—Install the library

| npm install --save-dev axios-mock-adapter |

Step 2⁠—Create and pass an Axios instance to Axios adapter

The following code creates an Axios instance and then passes it to the Axios adapter.

import axios, { AxiosRequestConfig } from 'axios';
import AxiosMockAdapter from 'axios-mock-adapter';
const axiosMockInstance = axios.create();
const axiosLiveInstance = axios.create();
export const axiosMockAdapterInstance= new AxiosMockAdapter(
  axiosMockInstance, 
  { delayResponse: 0 }
);
export default process.env.isAxioMock? axiosMockInstance : axiosLiveInstance;
Enter fullscreen mode Exit fullscreen mode

Now, we can import this file and use it where necessary.

Step 3⁠—Create the mock file

import { axiosMockAdapterInstance } from 'src/lib/axios';

mock
   .onGet('/api/social/profiles')
   .reply(() => {
     const profile: User = {
     id: 'u001',
     title: 'Manager',
     name: 'John Mayor',
     email: 'johne@example.com'
};

return [200, { User }];
Enter fullscreen mode Exit fullscreen mode

You can read more about Axios Mocking with React here.

Strategies for API Mocking in JavaScript Applications

An application’s request journey involves three major components:

  • Application
  • Request client
  • Server

The application calls a request client to make a request. The request client sends the request using HTTP to the server. After receiving the request, the server returns the necessary response. So, we can mock the request client or the server as we test the application.

Mocking the Request Client

The mock request client replaces the actual request client with a compatible client to mimic the responses. You can implement this methodology more simply by using a third-party library like Nock and MirageJS.

The logical component of mocking is in the client-side code, and you can control the requests or responses at very early stages. However, an actual request is not made to the server by the request client when using this method.

Mocking the Server

The other strategy for API mocking is mocking the server itself. In this case, the actual server gets replaced with a mock server that accepts requests. Then it returns responses from and to the request client. We can use several libraries to accomplish this server mocking strategy, including JSON Server and ExpressJS server.

This strategy is quite similar to the actual application behavior in production. The request client works completely as only the server is replaced here. But setting up and maintaining an entire server can be quite costly and complicated. Therefore, we can simplify the operations in server mocking to a certain extent by using the libraries mentioned previously.

Conclusion

This article discussed why API mocking techniques are necessary and what kind of strategies we can use for API mocking, along with several examples. Of course, whichever method or library you use depends on the requirements of the scenario and the environment, yet it is essential to make sure a bare minimum of application behavior change is occurring due to the mocking.

So, I hope you found this article helpful.

Thank you for reading!

Syncfusion’s Essential JS 2 is the only suite you will ever need to build an app. It contains over 65 high-performance, lightweight, modular, and responsive UI components in a single package. Download a free trial to evaluate the controls today.

If you have any questions or comments, you can contact us through our support forums, support portal, or feedback portal. We are always happy to assist you!

Related blogs

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .