A Mocking Service is a tool or technique used in front-end development to simulate back-end services during the development or testing phases. Instead of relying on actual APIs, a mocking service mimics the behavior of a real server by providing predefined responses to API requests. It allows front-end developers to work independently from back-end development. Even if the back-end API is not ready, front-end teams can continue building and testing their features using mock data.

What is the Mocking Service Worker?

Mock Service Worker (MSW) is an API mocking library for the browser and Node.js. With MSW, you can intercept outgoing requests, observe them, and respond to them using mocked responses. (Mock Service Worker introduction)

How to use it?

1. Install MSW

In your project directory, install msw using the following command:

npm install msw --save-dev

2. Initialize the MSW Service Worker

After installing MSW, you need to generate a service worker script. Run this command to create the public/mockServiceWorker.js file

npx msw init public/ --save

After running the command successfully, this will generate the mockServiceWorker.js file in your public directory.

public
├── mockServiceWorker.js

3. Create an MSW Handler and Browser Setup

Now, set up request handlers that define the mock responses for your API endpoints. Create a new folder for MSW mocks, usually named mocks.

src
├── mocks
│   ├── browser.ts  // MSW setup for the browser
│   ├── handlers.ts // Define the handlers for your mock API endpoint

Define API Handlers (handlers.ts)

Create handlers.ts in the mocks folder. This file will define the endpoints you want to mock and their responses. In this post, my mock handler will be set to intercept requests to /api/login.

// src/mocks/handlers.ts 
import { http, HttpResponse } from "msw"; 
import { ILogin, IUser } from "./types"; 

const USER: IUser[] = [
   { _id: "671510d3e4563ba0508e7679",
     username: "demo",
     email: "demo@mail.com",
     password: "newpassword",
   }, ]; 
const fakeToken = "fakeToken123456"; 

export const handlers = [
   // Example POST request to login a user
   http.post("/api/login", async ({ request }) => {
     const body = (await request.json()) as ILogin; 
     const foundUser = USER.find((item: IUser) => item.email === body.email); 

    if (!foundUser) {
       return HttpResponse.json(
         { message: "Invalid email or password" },
         { status: 401 }
       );
     } 

    return HttpResponse.json(
       {
         _id: foundUser._id,
         username: foundUser.username,
         email: foundUser.email,
         token: fakeToken,
       },
       { status: 200 }
     );
   }),
 ];

Set Up MSW for the Browser (browser.ts)

// src/mocks/browser.js 
import { setupWorker } from "msw/browser"; 
import { handlers } from "./handlers"; 

// Initialize the Service Worker with the request handlers 
export const worker = setupWorker(...handlers);

4. Start the MSW Worker in Development

In the main file (e.g. main.tsx), conditionally start the MSW worker only in development mode.

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./index.css";

async function enableMocking() {
  if (process.env.NODE_ENV !== "development") {
    return;
  }

  const { worker } = await import("./mocks/browser");

  // `worker.start()` returns a Promise that resolves
  // once the Service Worker is up and ready to intercept requests.
  return worker.start();
}

enableMocking().then(() => {
  createRoot(document.getElementById("root")!).render(
    <StrictMode>
      <App />
    </StrictMode>
  );
});

5. Setup to call the login API for Login page

Create an async callback function to call the login API.

const callApiLogin = useCallback(async (reqInfo: ILogin) => {
     const response = await fetch("/api/login", {
       method: "POST",
       headers: {
         "Content-Type": "application/json",
       },
       body: JSON.stringify(reqInfo),
     }); 
     const data = await response.json();   
     alert(JSON.stringify(data));
}, []);

Call the callback function on the submit event.

const onSubmit: SubmitHandler = useCallback(async (data) => {       
    callApiLogin(data);
},[callApiLogin]);

6. Run Your App with Mocked APIs

Now, when your app running in development mode, MSW will intercept API calls matching the endpoints defined in handlers.ts and return the mock responses.

npm run dev

In the browser, open the DevTools, [MSW] Mocking enabled. will be shown if MSW started successfully.

Provide the email and password, then click on the login button; the mocking service will respond with the data like a real back-end API.

Visualize the mock working in GIF.

Conclusion

Mocking Service Worker (MSW) is a robust and versatile library for building and managing mocking services in front-end development. It simplifies the process of simulating APIs, ensuring smooth development workflows and reliable testing environments. To explore its advanced features and unlock its full potential, you can refer to the official documentation on the MSW website.

References

  • https://mswjs.io/docs/getting-started
  • https://images.unsplash.com/photo-1433840496881-cbd845929862?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D