Nếu bạn viết các bài kiểm thử frontend, có lẽ bạn đã biết đến Mock Service Worker (MSW). Đây là thư viện hàng đầu để chặn các yêu cầu bên trong trình duyệt và Node, và đối với các bài kiểm thử đơn vị và thành phần thì rất khó có thư viện nào vượt qua được. Hướng dẫn này giải thích những gì MSW làm tốt, những hạn chế về khả năng mở rộng của nó, và khi nào một nền tảng tạo mock API được lưu trữ sẽ hợp lý hơn.
Mock Service Worker là gì?
Mock Service Worker là một thư viện JavaScript chặn các yêu cầu mạng tại nguồn. Trong trình duyệt, nó đăng ký một Service Worker để bắt các lệnh gọi fetch và XMLHttpRequest đi. Trong Node, nó vá lớp yêu cầu để các trình xử lý tương tự chạy trong Jest hoặc Vitest. Bạn viết các trình xử lý yêu cầu khớp với phương thức và đường dẫn, sau đó trả về bất kỳ phản hồi nào bạn muốn.

Thiết kế này rất thông minh. Mã ứng dụng của bạn vẫn gọi các API mạng thực. MSW nằm ở giữa và trả lời, vì vậy bạn không cần stub fetch hoặc thay đổi máy khách HTTP của mình. Các định nghĩa mock tương tự hoạt động trong các bài kiểm thử và trong một bản dựng phát triển đang chạy, đó là lý do tại sao rất nhiều nhóm React và Vue sử dụng nó. Bạn có thể tìm hiểu mã nguồn MSW trên GitHub để xem lớp chặn hoạt động như thế nào.
Một trình xử lý điển hình trông như thế này:
import { http, HttpResponse } from 'msw'
export const handlers = [
http.get('/api/users/:id', ({ params }) => {
return HttpResponse.json({ id: params.id, name: 'Ada Lovelace' })
}),
]
Đó là toàn bộ sức hấp dẫn. Mock nằm cạnh mã của bạn, được kiểm soát phiên bản cùng với các bài kiểm thử của bạn và chạy ở bất cứ đâu JavaScript của bạn chạy.
MSW tỏa sáng ở đâu
MSW rất phù hợp khi mock và bên tiêu thụ nằm trong cùng một codebase. Một vài trường hợp nó thực sự là công cụ phù hợp:
- Kiểm thử thành phần và đơn vị. Kết xuất một thành phần, để nó gửi các yêu cầu thực và trả về dữ liệu mẫu. Không cần cấu hình các test double. Nếu bạn so sánh nó với việc giám sát trực tiếp máy khách, hãy xem điều này khác với việc mock một lệnh gọi API trong Jest như thế nào.
- Phát triển frontend cục bộ. Xây dựng giao diện người dùng (UI) trước khi backend tồn tại. Chuyển đổi trình xử lý để mô phỏng trạng thái tải, lỗi hoặc trống theo yêu cầu.
- CI xác định. Các bài kiểm thử không chạm vào máy chủ thực, vì vậy chúng không bị lỗi do điều kiện mạng hoặc dữ liệu staging được chia sẻ.
- Một ngôn ngữ, một đội. Khi những người viết mock cũng là những người tiêu thụ nó, việc giữ các trình xử lý trong kho lưu trữ là cách đơn giản nhất.
Nếu đó là tình huống của bạn, có lẽ bạn không cần bất cứ điều gì khác. MSW miễn phí, mã nguồn mở và được xây dựng chính xác cho mục đích này.
Khi MSW bắt đầu gặp khó khăn
Điều khiến MSW trở nên tuyệt vời trong một kho lưu trữ duy nhất, tức là các mock tồn tại dưới dạng mã trong kho lưu trữ đó, cũng chính là điều hạn chế nó khi có nhiều người tham gia hơn. Đây là lúc các nhóm có xu hướng vượt qua giới hạn của nó.
Người tiêu thụ không phải JavaScript
Các trình xử lý MSW là JavaScript. Nếu đội di động của bạn viết Swift hoặc Kotlin, hoặc các bài kiểm thử tích hợp backend của bạn chạy bằng Go hoặc Python, họ không thể nhập các trình xử lý của bạn. Họ sẽ cần các mock riêng, và chúng có thể khác với của bạn. Một máy chủ mock không phụ thuộc ngôn ngữ, giao tiếp HTTP qua một URL thực, hoạt động cho mọi máy khách, bất kể ngôn ngữ nào.
Các mock được chia sẻ, luôn hoạt động
MSW chạy bên trong một tiến trình. Không có URL chung mà kỹ sư QA, nhà thiết kế hoặc nhóm đối tác có thể truy cập từ máy của họ. Khoảnh khắc bạn muốn một điểm cuối mà nhiều người sử dụng cùng lúc, bạn cần một máy chủ mock được lưu trữ với địa chỉ ổn định, chứ không phải một Service Worker bị ràng buộc với một tab trình duyệt.
Quy trình làm việc ưu tiên thiết kế và dựa trên schema
Nếu bạn thiết kế API trong OpenAPI trước khi viết mã, bạn muốn các mock được tạo tự động từ đặc tả, để mock không thể mâu thuẫn với hợp đồng. MSW yêu cầu bạn tự viết tay các trình xử lý. Tạo mock trực tiếp từ một schema là một mô hình khác. Bạn có thể đọc thêm về cách tiếp cận đó trong hướng dẫn này về tạo mock API và các mô hình xung quanh nó.
Dữ liệu động, thực tế ở quy mô lớn
MSW trả về bất cứ thứ gì trình xử lý của bạn mã hóa. Đối với dữ liệu giống như thật trên nhiều trường, bạn tự viết logic đó. Các nền tảng tích hợp tính năng tạo dữ liệu kiểu faker và suy luận tên trường mang lại cho bạn các phản hồi thực tế mà không cần tự tạo từng cái một.
MSW so với một nền tảng tạo mock API đầy đủ
Dưới đây là một so sánh trung thực. Không có cột nào “tốt hơn” một cách trừu tượng; chúng giải quyết các vấn đề khác nhau.
| Khả năng | Mock Service Worker | Nền tảng API được lưu trữ (ví dụ Apidog) |
|---|---|---|
| Chạy bên trong kiểm thử đơn vị/thành phần JS | Có, nguyên bản | Không, nó không phải là thư viện kiểm thử JS |
| Không phụ thuộc ngôn ngữ qua HTTP | Không (chỉ JS) | Có, bất kỳ máy khách nào |
| URL được chia sẻ cho toàn đội | Không | Có, máy chủ mock được lưu trữ |
| Tạo mock từ OpenAPI | Thủ công | Tự động từ schema |
| Tạo dữ liệu thông minh/động | Mã hóa thủ công | Tích hợp sẵn |
| Sống trong repo của bạn cùng với các bài kiểm thử | Có | Lưu trữ trong dự án được chia sẻ |
| Chi phí | Miễn phí, mã nguồn mở | Gói miễn phí + gói trả phí |
Điểm mấu chốt: MSW là lựa chọn đúng đắn cho các bài kiểm thử frontend và phát triển cục bộ. Một nền tảng như Apidog là lựa chọn đúng đắn khi mock cần được chia sẻ, không phụ thuộc ngôn ngữ hoặc được điều khiển bởi một đặc tả.
Apidog là sự bổ sung, không phải sự thay thế
Nói rõ hơn, Apidog không phải là một thay thế trực tiếp cho MSW bên trong Jest hoặc Vitest. Nó không phải là một thư viện JavaScript mà bạn nhập vào một tệp kiểm thử. Hãy coi nó là lớp trên các bài kiểm thử đơn vị của bạn, nơi các mock trở thành một tài nguyên được chia sẻ, không phụ thuộc ngôn ngữ cho toàn đội.
Đây là cách nó hoạt động trong thực tế. Bạn thiết kế hoặc nhập một API vào Apidog, và nó tự động tạo một điểm cuối mock từ schema. Mock có một URL thực mà các đồng đội frontend, di động và QA của bạn đều có thể gọi. Apidog điền các phản hồi bằng dữ liệu thực tế bằng cách suy luận từ tên trường, vì vậy một trường tên là email sẽ trả về một địa chỉ email và createdAt sẽ trả về một ngày tháng. Bạn cũng có thể viết các quy tắc tùy chỉnh khi bạn cần một phản hồi 500 cụ thể hoặc một trường hợp biên đặc biệt.

Vì mock đến từ cùng một schema với thiết kế và kiểm thử của bạn, nó luôn đồng bộ với hợp đồng. Đó là phần mà các trình xử lý được viết thủ công không thể đảm bảo. Nếu bạn muốn xem việc tạo mock từ schema so sánh giữa các công cụ như thế nào, bài tổng hợp các công cụ tạo mock API tốt nhất này sẽ đặt các tùy chọn cạnh nhau.

Một sự phân chia thực tế mà nhiều đội lựa chọn:
- Giữ MSW cho các bài kiểm thử thành phần và đơn vị bên trong kho lưu trữ frontend.
- Sử dụng một mock được lưu trữ cho tích hợp đa nhóm, trình diễn và bất kỳ người tiêu dùng không phải JS nào.
Bạn không chọn một cái. Bạn sử dụng từng cái ở nơi nó phù hợp. Tải Apidog nếu bạn muốn thử khía cạnh được lưu trữ cùng với thiết lập MSW hiện có của mình.
Các lựa chọn thay thế MSW khác đáng biết
MSW không phải là thư viện tạo mock duy nhất, và một nền tảng không phải là lựa chọn duy nhất của bạn. Tùy thuộc vào stack của bạn:
- Mockoon là một ứng dụng máy tính để bàn để khởi động nhanh các máy chủ mock cục bộ, với giao diện người dùng đồ họa (GUI) thay vì mã.
- WireMock là một máy chủ mock dựa trên Java, mạnh mẽ cho các đội JVM và kiểm thử hợp đồng.
- Prism của Stoplight tạo mock trực tiếp từ một tệp OpenAPI qua dòng lệnh.
- json-server biến một tệp JSON thành một REST API nhanh chóng để tạo mẫu.
Mỗi cái đều có ưu và nhược điểm. WireMock và Prism hướng về công việc backend và hợp đồng; Mockoon và json-server hướng về thiết lập cục bộ nhanh chóng. Nếu vấn đề của bạn đặc biệt là “MSW không thể giúp các đồng đội không phải JS của tôi”, thì bất kỳ máy chủ mock dựa trên HTTP nào cũng giải quyết được. Để có một góc nhìn rộng hơn về frontend, hãy xem các đội xử lý việc tạo mock API trong React với Axios như thế nào.
Các câu hỏi thường gặp
MSW có miễn phí không?
Có. Mock Service Worker là mã nguồn mở theo giấy phép MIT và miễn phí sử dụng trong bất kỳ dự án nào, dù thương mại hay không. Bạn chỉ bắt đầu trả tiền khi chuyển sang một nền tảng được lưu trữ cho các mock được chia sẻ, và các công cụ như Apidog cũng có gói miễn phí cho việc đó.
Apidog có thể thay thế MSW trong các bài kiểm thử đơn vị của tôi không?
Không, và bạn không nên cố gắng làm điều đó. MSW chặn các yêu cầu bên trong trình chạy kiểm thử JavaScript của bạn. Apidog là một nền tảng được lưu trữ, không phải là một thư viện có thể nhập, vì vậy nó không thể nằm bên trong Jest hoặc Vitest như cách MSW làm. Thay vào đó, hãy sử dụng Apidog cho các mock được chia sẻ, đa nhóm hoặc dựa trên schema. Nếu bạn chỉ tập trung vào phía trình chạy kiểm thử, hướng dẫn về cách tạo mock lệnh gọi API này sẽ bao gồm các cách tiếp cận trong mã.
MSW hoạt động trong Node, hay chỉ trong trình duyệt?
Cả hai. Trong trình duyệt, MSW sử dụng một Service Worker. Trong Node, nó vá lớp yêu cầu để các trình xử lý tương tự chạy trong Jest, Vitest hoặc bất kỳ môi trường kiểm thử Node nào. Chế độ kép đó là một trong những điểm mạnh lớn nhất của nó đối với các đội JS full-stack.
Khi nào tôi nên chuyển từ MSW sang máy chủ mock được lưu trữ?
Chuyển đổi, hay đúng hơn là bổ sung, khi mock cần được chia sẻ. Các dấu hiệu rõ ràng nhất: một máy khách không phải JavaScript cần nó, nhiều người cần cùng một URL ổn định, hoặc bạn thiết kế API ưu tiên đặc tả và muốn các mock được tạo tự động từ OpenAPI.
Kết luận
MSW xuất sắc trong việc nó được tạo ra: chặn các yêu cầu bên trong JavaScript cho các bài kiểm thử frontend và đơn vị. Nó không cố gắng trở thành một mock được chia sẻ, lưu trữ, không phụ thuộc ngôn ngữ, và điều đó không sao cả. Khi các mock của bạn cần thoát khỏi kho lưu trữ, khi các ngôn ngữ khác hoặc các đội khác cần chúng, hoặc khi bạn muốn chúng được tạo từ một đặc tả, đó là lúc nên thêm một nền tảng đầy đủ bên cạnh nó.
Apidog xử lý phía được chia sẻ, dựa trên schema: một máy chủ mock được lưu trữ với một URL thực, các mock tự động từ thiết kế OpenAPI của bạn, và dữ liệu thực tế ngay lập tức. Giữ MSW ở những điểm mạnh của nó, và để Apidog bao quát mọi thứ ngoài giới hạn của trình chạy kiểm thử của bạn. Tải Apidog và trỏ frontend của bạn đến một mock được chia sẻ để thấy sự khác biệt.
