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.
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.
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:
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.
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.
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 |
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"} ] }
After that, start the server with the following command.
json-server --watch users.json --port 8000 |
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} ); };
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.
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.
MirageJS installation is quite simple with the following command.
npm install --save-dev miragejs |
import { createServer } from 'miragejs'; export function makeServer() { let server = createServer(); return server; }
The createServer function creates a new mock server instance.
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') );
The if condition in the previous code is for using the MirageJS server only in the development phase.
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; }
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(); }); }
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.
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.
npm install --save-dev axios-mock-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;
Now, we can import this file and use it where necessary.
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 }];
You can read more about Axios Mocking with React here.
An application’s request journey involves three major components:
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.
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.
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.
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!