Nock là gì? Mock HTTP request trong Node.js (và giải pháp thay thế không cần code)

nock npm là gì? Tìm hiểu cách nock giả lập các yêu cầu HTTP trong các bài kiểm thử đơn vị của Node.js, kèm theo ví dụ code và khi nào nên sử dụng một máy chủ mock dùng chung thay thế.

Ashley Innocent

Ashley Innocent

24 tháng 6 2026

Nock là gì? Mock HTTP request trong Node.js (và giải pháp thay thế không cần code)

Apidog cho doanh nghiệp

Triển khai tại chỗ

SSO & RBAC

Tuân thủ SOC 2

Khám phá Apidog Enterprise

Nếu các bài kiểm tra Node.js của bạn thất bại vì API bên thứ ba bị sập, chậm hoặc bị giới hạn tốc độ, bạn không gặp vấn đề về code. Bạn gặp vấn đề về phụ thuộc. Giải pháp là giả lập lớp HTTP để các bài kiểm tra đơn vị của bạn chạy theo cùng một cách mỗi lần, và nock là gói npm mà hầu hết các nhà phát triển Node đều tìm đến. Hướng dẫn này giải thích nock là gì, trình bày một ví dụ hoạt động nhỏ và chỉ ra nơi mà một máy chủ giả lập chia sẻ phù hợp hơn là việc chặn trong quá trình. Để tham khảo thư viện đầy đủ, kho lưu trữ GitHub của nock là nguồn thông tin đáng tin cậy.

nút

nock là gì?

nock là một thư viện giả lập và quản lý kỳ vọng máy chủ HTTP dành cho Node.js. Nó hoạt động bằng cách ghi đè lên các module httphttps của Node trong thời gian chạy, nhờ đó mọi yêu cầu gửi đi mà mã của bạn thực hiện đều có thể bị chặn và phản hồi bằng một phản hồi được định sẵn. Không có gì rời khỏi máy của bạn. Cuộc gọi mạng không bao giờ xảy ra.

Điều này quan trọng đối với các bài kiểm tra đơn vị. Khi bạn kiểm tra một hàm gọi đến API bên ngoài, bạn không muốn truy cập dịch vụ thực. Các cuộc gọi thực chậm, tốn tiền, có thể thất bại vì những lý do không liên quan đến mã của bạn và chúng làm cho bộ kiểm thử của bạn không thể đoán trước được. nock cho phép bạn nói “khi mã của tôi thực hiện yêu cầu GET đến URL này, hãy trả về JSON chính xác này với mã trạng thái này.” Bài kiểm tra của bạn sau đó sẽ khẳng định cách hàm của bạn xử lý phản hồi đó.

nock chỉ dành cho Node.js. Nó móc nối vào ngăn xếp HTTP gốc, vì vậy nó hoạt động với fetch, axios, got, node-fetch và bất kỳ thứ gì khác được xây dựng trên http/https. Nó có hàng triệu lượt tải xuống hàng tuần và đã là lựa chọn mặc định để kiểm thử backend trong nhiều năm. Bạn cài đặt nó như một dependency dành cho phát triển vì nó chỉ chạy trong các bài kiểm thử, không bao giờ trong môi trường sản xuất.

Một ví dụ nock nhỏ

Giả sử bạn có một hàm lấy người dùng từ một API. Đây là hàm đó:

// user-service.js
export async function getUser(id) {
  const res = await fetch(`https://api.example.com/users/${id}`);
  if (!res.ok) throw new Error(`Request failed: ${res.status}`);
  return res.json();
}

Bây giờ, đây là một bài kiểm tra sử dụng nock để chặn yêu cầu:

// user-service.test.js
import nock from 'nock';
import { getUser } from './user-service.js';

test('returns the user when the API responds', async () => {
  nock('https://api.example.com')
    .get('/users/42')
    .reply(200, { id: 42, name: 'Ada Lovelace' });

  const user = await getUser(42);
  expect(user).toEqual({ id: 42, name: 'Ada Lovelace' });
});

Đọc từ trên xuống dưới. nock('https://api.example.com') đặt máy chủ bạn muốn chặn. .get('/users/42') khớp với phương thức và đường dẫn. .reply(200, {...}) định nghĩa trạng thái và nội dung trả về. Khi getUser(42) chạy, cuộc gọi mạng thực sẽ được thay thế và phản hồi được định sẵn của bạn sẽ được trả về.

Bạn có thể giả lập lỗi theo cùng một cách, đây là phần mà mọi người thường quên kiểm tra:

test('throws when the API returns 500', async () => {
  nock('https://api.example.com')
    .get('/users/99')
    .reply(500);

  await expect(getUser(99)).rejects.toThrow('Request failed: 500');
});

Kiểm tra các trường hợp không mong muốn là nơi việc giả lập thể hiện giá trị của nó. Bạn không thể yêu cầu một API thực trả về lỗi 500 một cách đáng tin cậy theo yêu cầu, nhưng bạn có thể giả lập một lỗi chỉ trong một dòng. Nếu mục tiêu chính của bạn là mô phỏng lỗi, hướng dẫn về cách giả lập phản hồi lỗi máy chủ nội bộ 500 này sẽ đi sâu hơn.

Các tính năng hữu ích của nock cần biết

Một vài phương thức thường xuyên xuất hiện khi bạn đã vượt qua những kiến thức cơ bản.

Một thói quen đáng xây dựng sớm: khẳng định rằng tất cả các giả lập của bạn đã thực sự được sử dụng. Gọi scope.done() trên một bộ chặn (hoặc nock.isDone()) và bài kiểm tra sẽ thất bại nếu một yêu cầu được mong đợi không bao giờ được kích hoạt. Điều đó biến một cuộc gọi bị bỏ lỡ im lặng thành một lỗi lớn.

Khi nock không còn là công cụ phù hợp

nock được xây dựng cho một công việc và làm rất tốt: chặn HTTP bên trong một tiến trình Node duy nhất trong quá trình kiểm thử tự động. Khoảnh khắc nhu cầu của bạn vượt qua ranh giới tiến trình, mô hình đó bắt đầu trở nên căng thẳng.

Đây là giới hạn. Các giả lập nock tồn tại bên trong tệp kiểm thử của bạn, trong môi trường chạy của bạn, trong ngôn ngữ của bạn. Một nhà phát triển front-end không thể trỏ trình duyệt của họ vào thiết lập nock của bạn. Một kỹ sư di động không thể truy cập nó từ một trình giả lập. Nhóm QA của bạn không thể chạy các kiểm tra thủ công chống lại nó. Một bộ sưu tập Postman không thể tiếp cận nó. Giả lập chỉ tồn tại khi tiến trình Jest hoặc Mocha của bạn đang chạy, và chỉ cho mã trong cùng tiến trình đó.

Điều đó tốt cho các bài kiểm tra đơn vị và chính xác là những gì nock được thiết kế. Nhưng rất nhiều tình huống thực tế cần một giả lập tồn tại ở nơi mọi người đều có thể truy cập:

Đối với những trường hợp đó, bạn cần một máy chủ giả lập, một thứ gì đó lắng nghe trên một URL thực và trả về phản hồi cho bất kỳ ai gọi nó. Nếu bạn đang cân nhắc hai ý tưởng này, máy chủ giả lập so với máy chủ thực và giải thích rộng hơn về giả lập API đều trình bày các đánh đổi.

nock so với máy chủ giả lập được lưu trữ (Apidog)

Hãy coi đây là hai lớp thay vì một cuộc cạnh tranh. nock xử lý việc chặn trong mã cho các bài kiểm tra đơn vị. Một công cụ như Apidog cung cấp cho bạn một máy chủ giả lập chung, dựa trên lược đồ cho mọi thứ xảy ra bên ngoài một tiến trình kiểm thử duy nhất. Nhiều nhóm sử dụng cả hai.

Apidog tạo ra một máy chủ giả lập trực tiếp từ thiết kế API của bạn. Bạn định nghĩa một điểm cuối và lược đồ của nó, và Apidog phục vụ các phản hồi thực tế tại một URL trực tiếp, với các quy tắc giả lập thông minh tạo ra dữ liệu hợp lý từ tên và kiểu trường. Không có test harness, không cần thiết lập riêng cho từng bài kiểm thử, không bị khóa ngôn ngữ. Bất kỳ ai có URL đều nhận được các phản hồi tương tự.

nock Máy chủ giả lập Apidog
Nơi nó chạy Trong tiến trình kiểm thử Node của bạn Máy chủ được lưu trữ với URL thực
Tốt nhất cho Kiểm thử đơn vị, mô phỏng lỗi Tích hợp, kiểm thử thủ công, công việc giữa các nhóm
Ai có thể tiếp cận Mã trong cùng tiến trình Bất kỳ client nào có URL
Thiết lập Code trong mỗi tệp kiểm thử Được tạo từ lược đồ API của bạn
Ngôn ngữ Chỉ Node.js Bất kỳ client, bất kỳ ngôn ngữ nào
Dữ liệu thực tế Bạn viết từng phản hồi Giả lập thông minh từ lược đồ và tên trường
Chia sẻ Không thể chia sẻ Chia sẻ trên toàn bộ nhóm

Để rõ ràng về phạm vi: Apidog không thay thế nock bên trong các bài kiểm tra đơn vị Jest hoặc Mocha của bạn. Nếu bạn cần chặn một cuộc gọi fetch trong một bài kiểm tra duy nhất và khẳng định kết quả, nock vẫn là công cụ phù hợp. Apidog can thiệp khi giả lập cần một địa chỉ mà những người khác và các công cụ khác có thể truy cập. Để xem xét thực tế phía máy chủ, hãy xem hướng dẫn thực tế về giả lập API để kiểm thử. Bạn có thể tải xuống Apidog và tạo một giả lập từ tệp OpenAPI hiện có trong vài phút.

Các lựa chọn thay thế khác cho nock

nock không phải là thư viện duy nhất trong lĩnh vực này, và lựa chọn phù hợp phụ thuộc vào nơi mã của bạn chạy.

Câu hỏi quyết định luôn giống nhau. Bạn đang kiểm tra logic bên trong một tiến trình, hay bạn cần một API giả tồn tại trên mạng? nock và MSW trả lời câu hỏi đầu tiên. Một máy chủ giả lập được lưu trữ trả lời câu hỏi thứ hai.

Các câu hỏi thường gặp

nock có miễn phí không?

Có. nock là mã nguồn mở theo giấy phép MIT và miễn phí cài đặt từ npm. Bạn thêm nó như một dev dependency và sử dụng nó trong bộ kiểm thử của mình mà không tốn phí.

nock có hoạt động với fetch và axios không?

Có. Bởi vì nock chặn ở lớp http/https của Node, nó hoạt động với bất kỳ client nào được xây dựng trên các module đó, bao gồm fetch, axios, gotnode-fetch gốc. Bạn viết cùng một bộ chặn bất kể mã của bạn sử dụng cái nào.

Tôi có thể sử dụng nock trong trình duyệt không?

Không. nock chỉ dành cho Node.js vì nó vá các module HTTP của Node, vốn không tồn tại trong trình duyệt. Để giả lập phía trình duyệt, hãy sử dụng MSW hoặc trỏ front-end của bạn đến một máy chủ giả lập được lưu trữ. Tổng quan này về các API giả lập trong JavaScript sẽ hướng dẫn bạn các tùy chọn trình duyệt.

Sự khác biệt giữa nock và một máy chủ giả lập là gì?

nock chặn các yêu cầu bên trong tiến trình kiểm thử của bạn và không bao giờ mở một cổng thực. Một máy chủ giả lập lắng nghe trên một URL thực mà bất kỳ client nào cũng có thể gọi. Sử dụng nock cho các bài kiểm tra đơn vị; sử dụng máy chủ giả lập khi front-end, QA hoặc các nhóm khác cần truy cập cùng một phản hồi giả.

Tổng kết

nock là lựa chọn đáng tin cậy để giả lập HTTP trong các bài kiểm tra đơn vị Node.js. Nó chặn các yêu cầu gửi đi trong tiến trình, trả về các phản hồi bạn định nghĩa và làm cho bộ kiểm thử của bạn nhanh chóng và có tính xác định, bao gồm cả các đường dẫn lỗi mà bạn không thể kích hoạt đối với một API thực. Hãy tiếp tục sử dụng nó cho mục đích đó.

Khi giả lập cần rời khỏi tệp kiểm thử của bạn, khi giao diện người dùng, QA hoặc một nhóm khác phải truy cập cùng một điểm cuối, hãy tìm đến một máy chủ giả lập chia sẻ thay thế. Apidog tạo ra một máy chủ từ lược đồ API của bạn và phục vụ dữ liệu thực tế tại một URL trực tiếp, vì vậy mọi người đều xây dựng dựa trên cùng một hợp đồng trước khi backend sẵn sàng. Tải xuống Apidog và biến thông số kỹ thuật OpenAPI của bạn thành một giả lập hoạt động trong vài phút.

Thực hành thiết kế API trong Apidog

Khám phá cách dễ dàng hơn để xây dựng và sử dụng API