Mock API bằng Mock Service Worker (MSW)

Mock Service Worker hay gọi tắt là MSW là một thư viện khá hay dùng để mock API. Trong bài viết này mình sẽ giới thiệu đồng thời viết một React App nho nhỏ để test thử thư viện. Để hiểu rõ về bài viết này, bạn cần có chút kiến thức về Javascript và React.

Khi bắt đầu một dự án làm Web Application, thông thường front-end và back-end sẽ được phát triển song song. Khi làm như vậy, lúc front-end cần gọi đến API của back-end, thì API thường sẽ chưa có do endpoint cũng đang được code. Để việc phát triển được thuận lợi và đảm bảo chất lượng thì việc mock là vô cùng cần thiết. Đồng thời việc mock cũng là để tiện lợi cho việc viết unit test.

Setup môi trường

Để bắt đầu thì mình sẽ tạo một project React App, cách đơn giản và nhanh nhất là sử dụng CreateReactApp. Bật terminal lên và ta gõ lần lượt các lệnh sau.

npx create-react-app my-react-app
cd my-react-app
npm start

Nư vậy, ta đã có ngay một React App để sử dụng. Ta sẽ cài thêm thư viện axios để thực hiện việc gọi API.

npm install axios

Sau đó ta xóa toàn bộ phần thân hàm và cập nhật file App.js như sau.

import "./App.css";
import axios from "axios";
import { useEffect, useState } from "react";

function App() {
    const [threeDays, setThreeDays] = useState({});
    const [tomorrow, setTomorrow] = useState({});

    useEffect(() => {
        fetch("/getTomorrowWeather")
            .then((response) => response.json())
            .then((data) => {
                setTomorrow(data);
            });

        axios.get("/getWeather?days=3").then((result) => {
            setThreeDays(result.data);
        });
    }, []);

    return (
        <>
            <h1>The weather tomorrow will be: {tomorrow.info}</h1>
            <h1>The weather of the next 3 days will be: {threeDays.info}</h1>
        </>
    );
}

export default App;

Trong file này, ta thực hiện việc gọi API bằng 2 cách là axiosfetch. Đến cuối cùng ta sẽ thấy được, dù ta sử dụng cách nào để gọi đến API, do ta mock ở tầng network nên dữ liệu vẫn sẽ được trả về. Điều này giúp cho ta không phải mock cho từng kiểu gọi khác nhau.

Để đơn giản, ta sẽ hiển thị dữ liệu bằng hai thẻ <h1>. Như vậy là đủ đơn giản để demo mock API.

Cài đặt Mock API

Ta sẽ thực hiện cài đặt MSW bằng câu lệnh sau.

npm install msw --save-dev

Ở bước tiếp theo ta cần tạo data để mock. Đầu tiên ta sẽ tạo một folder mocks ở trong thư mục src và tạo 2 file json trong thư mục này.

tomorrow.json

{
    "info": "20 Celsius, rainy!"
}

threedays.json

{
    "info": "Day 1: 20 Celsius, rainy! - Day 2: 25 Celsius, rainy! - Day 3: 30 Celsius, sunny!"
}

Để đơn giản mình để tất cả là string. Sau đó ta sẽ tạo file handler.js ở cùng thư mục. Trong file này ta sẽ tạo ra các API giả lập tương ứng với 2 API được gọi ở trong React App.

import { rest } from "msw";
import TomorrowData from "./tomorrow.json";
import ThreeDays from "./threedays.json";

export const handlers = [
    rest.get("/getTomorrowWeather", (_req, res, ctx) => {
        return res(ctx.json(TomorrowData), ctx.status(200));
    }),

    rest.get("/getWeather", (_req, res, ctx) => {
        const numberOfDays = _req.url.searchParams.get("days");
        if (numberOfDays === "3") {
            return res(ctx.json(ThreeDays), ctx.status(200));
        } else {
            return null;
        }
    }),
];

Tiếp theo, ta sẽ cần đăng kí service worker để làm nơi xử lý các request. Ta sẽ không cần phải tự tạo mà chỉ cần run câu lệnh sau để copy file worker từ trong thư viện ra thư mục server giả lập là public.

npx msw init public/ --save

Sau đó ta sẽ config worker trong thư mục mocks bằng cách tạo file browser.js như sau.

import { setupWorker } from "msw";
import { handlers } from "./handlers";

export const worker = setupWorker(...handlers);

Cuối cùng ta cập nhật câu lệnh if vào file index.js. Mục đích là để chỉ thực hiện mock API trong môi trường development.

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

const root = ReactDOM.createRoot(document.getElementById("root"));

if (process.env.NODE_ENV === "development") {
    const { worker } = require("./mocks/browser");
    worker.start();
}

root.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Chạy thử

Mọi thứ đã xong, ta sẽ run bằng lệnh npm run start. Kết quả hiện lên màn hình sẽ như sau.

The weather tomorrow will be: 20 Celsius, rainy!
The weather of the next 3 days will be: Day 1: 20 Celsius, rainy! - Day 2: 25 Celsius, rainy! - Day 3: 30 Celsius, sunny!

Bật developer tool lên, chúng ta có thể thấy MSW đang tự động handle các request.

Kết luận

Như vậy mình đã giới thiệu một cách tổng quan cho các bạn Mock Service Worker (mswjs), một công cụ để Mock API đơn giản mà hiệu quả. Mã nguồn của đoạn code trên các bạn có thể tìm thấy tại đây. Cảm ơn các bạn đã đọc bài viết. Happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *