Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn là QA của một startup fintech tại TP.HCM. Team quyết định làm tính năng "lịch sử giao dịch" trong app. Anh backend nói: "API /transactions phải hai tuần nữa mới xong, còn phải xử lý phân trang, filter, chờ team payment cấp dữ liệu." Anh frontend thì cần dữ liệu để dựng màn hình ngay hôm nay. Còn bạn — QA — cần một endpoint để viết test case trước khi có backend thật.
Cả ba người đều đang chờ nhau. Đây chính là "nút thắt cổ chai" kinh điển trong phát triển phần mềm: frontend chờ backend, backend chờ dữ liệu, QA chờ tất cả. Mỗi ngày chờ là một ngày sprint trôi qua vô ích.
Mock server là lời giải. Nó là một API "giả" nhưng chạy thật trên internet, trả về những response mà bạn định nghĩa trước. Frontend gọi vào nó y như gọi API thật, QA viết test case dựa trên nó, và tất cả cùng làm việc song song mà không ai phải chờ ai. Khi backend thật xong, bạn chỉ việc đổi URL.
Trong bài này chúng ta sẽ đi sâu vào Mock Server của Postman — cách nó hoạt động, cách tạo, và quan trọng nhất là cách dùng nó để phá vỡ nút thắt cổ chai giữa frontend và backend. Đây là một trong những kỹ năng tạo ra giá trị rõ ràng nhất mà một QA/tester có thể mang lại cho team.
Khái niệm cốt lõi
Mock server là gì
Mock server là một máy chủ HTTP do Postman host, có một URL công khai dạng https://<mock-id>.mock.pstmn.io. Khi ai đó gửi request tới URL này, Postman không gọi tới hệ thống thật của bạn. Thay vào đó, nó tìm trong collection một example (ví dụ response đã lưu) khớp với request, rồi trả về đúng nội dung đã lưu đó.
Điểm mấu chốt cần nhớ: Mock server sống nhờ examples, không phải nhờ request. Một mock chỉ trả về được thứ mà bạn đã lưu sẵn dưới dạng example. Không có example, mock trả về lỗi. Đây là nguồn gốc của phần lớn sự bối rối khi mới dùng.
Example — trái tim của mock
Trong Postman, mỗi request có thể đính kèm nhiều examples. Một example là một cặp (request mẫu, response mẫu) đã được đóng băng: method, path, query, và đặc biệt là status code + body + header của response. Bạn có thể lưu một example "200 thành công", một example "404 không tìm thấy", một example "401 hết hạn token" — tất cả cho cùng một endpoint.
Khi mock nhận request, nó dùng thuật toán matching để chọn example phù hợp nhất dựa trên method, path và query params. Response của example đó được trả về nguyên văn.
Static mock vs Dynamic mock
Có hai cấp độ dùng mock:
- Static mock: example trả về body cố định.
{"balance": 500000}thì lần nào gọi cũng ra500000. Đơn giản, đủ dùng 80% trường hợp. - Dynamic mock: dùng biến templating của Postman như
{{$randomInt}},{{$randomFullName}},{{$guid}}ngay trong body example. Mỗi lần gọi, mock sinh dữ liệu ngẫu nhiên khác nhau — giúp frontend test được nhiều tình huống dữ liệu mà không cần bạn tạo hàng chục example.
Mock server khác gì với các công cụ liên quan
Đừng nhầm mock server với những thứ đã học/ sẽ học ở bài khác:
- Nó không phải monitor (bài 18 — chạy collection theo lịch).
- Nó không phải một assertion phức tạp (bài 2).
- Nó tập trung vào một mục tiêu duy nhất: phục vụ response giả để hai team phát triển song song. Đây chính là ranh giới nội dung của bài 19.
Tình huống thực tế
Tình huống 1 — Startup giao đồ ăn "FoodFast" và nút thắt hai tuần
FoodFast là một startup giao đồ ăn giả định tại Đà Nẵng, team 12 người. Sprint tháng này có tính năng "theo dõi tài xế real-time" (GET /orders/{id}/driver-location). Backend ước tính cần 10 ngày vì phải tích hợp với hệ thống GPS của bên thứ ba. Frontend chỉ có 6 ngày trong sprint.
QA của team, chị Hạnh, tạo một mock server. Chị cùng backend thống nhất "hợp đồng" (contract) của response: trả về {"lat": 16.047, "lng": 108.206, "status": "on_the_way", "eta_minutes": 12}. Chị lưu ba example: một cho on_the_way, một cho arrived, một cho delivered. Với example on_the_way, chị dùng {{$randomInt}} cho eta_minutes để frontend test được nhiều giá trị đếm ngược.
Kết quả: frontend dựng xong màn hình bản đồ trong 4 ngày, dùng mock URL. Ngày backend thật xong, họ đổi biến môi trường {{base_url}} từ mock sang server staging — không sửa một dòng code frontend nào. Sprint về đích đúng hạn.
Bài học: giá trị lớn nhất của mock không nằm ở kỹ thuật, mà ở chỗ nó buộc cả team thống nhất contract trước. Cái "hợp đồng response" đó chính là tài sản thật sự.
Tình huống 2 — QA test được cả các trường hợp lỗi mà backend chưa build
Vẫn ở FoodFast. Backend mới chỉ code xong "happy path" — đơn hàng thành công. Nhưng chị Hạnh cần test màn hình xử lý lỗi: hết món (409 Conflict), tài xế hủy (410 Gone), server quá tải (503).
Backend thật chưa mô phỏng được các lỗi này. Nhưng trên mock, chị chỉ cần lưu thêm ba example với status code tương ứng và body lỗi phù hợp. Bằng cách gọi mock với một query param đặc biệt (ví dụ ?scenario=out_of_stock), Postman match đúng example 409 và trả về.
Kết quả: frontend có thể dựng và test toàn bộ UI báo lỗi trước khi backend thật hỗ trợ những lỗi đó. Khi backend hoàn thiện, các UI lỗi đã sẵn sàng, không phải làm gấp vào cuối sprint.
Bài học: mock giỏi nhất ở việc mô phỏng các nhánh khó tái tạo — lỗi mạng, timeout, edge case. Đây là nơi mock tiết kiệm nhiều thời gian nhất, vì tạo lỗi thật trên backend thường rất tốn công.
Tình huống 3 — Cạm bẫy "mock nói dối" tại một ngân hàng số
Một team ngân hàng số (giả định, đặt tên "MB-lite") dùng mock rất hăng. Frontend build toàn bộ luồng chuyển tiền dựa trên mock trả {"status": "success"}. Đến ngày tích hợp backend thật, mọi thứ vỡ: backend thật trả {"result": {"state": "SUCCESS"}} — cấu trúc JSON khác hẳn. Frontend phải viết lại một nửa.
Nguyên nhân: mock được tạo tách rời backend, không ai đảm bảo example khớp với response thật. Mock đã "nói dối" suốt hai tuần.
Bài học: mock chỉ đáng tin khi example của nó phản ánh đúng contract thật. Cách phòng tránh: (1) sinh example từ định nghĩa OpenAPI chung, hoặc (2) mỗi khi backend chốt một endpoint, cập nhật ngay example tương ứng. Mock là công cụ tuyệt vời, nhưng "mock lệch thực tế" còn nguy hiểm hơn không có mock, vì nó tạo cảm giác an toàn giả tạo.
Hướng dẫn từng bước
Bước 1 — Chuẩn bị collection và example
- Tạo (hoặc mở) collection chứa các request bạn muốn mock, ví dụ
FoodFast API. - Tạo một request, chẳng hạn
GET {{url}}/orders/123/driver-location. - Gửi request (hoặc nếu chưa có backend, nhấn Send rồi bỏ qua kết quả) và bấm Save as Example. Nếu chưa có response, mở example thủ công và tự điền status code
200+ body JSON mong muốn. - Đặt tên example rõ ràng:
Driver on the way - 200.
Bước 2 — Tạo mock server
- Ở panel bên trái, đưa chuột vào collection → nhấn dấu ... → chọn Mock collection. (Hoặc: New → Mock Server.)
- Đặt tên mock, ví dụ
foodfast-mock. - Chọn environment để Postman tự lưu mock URL vào một biến (rất nên làm, thường đặt tên biến
url). - Nếu API nhạy cảm, tick Make mock server private — khi đó mọi request phải kèm header
x-api-keyvới API key của bạn. - Nhấn Create Mock Server. Postman sinh ra URL dạng
https://a1b2c3.mock.pstmn.io.
Bước 3 — Gọi thử mock
- Tạo request mới trỏ tới
{{url}}/orders/123/driver-location. - Send. Bạn sẽ nhận đúng body của example
Driver on the way - 200. - Nếu nhận lỗi
"no matching request", nghĩa là mock không tìm thấy example khớp path/method — xem phần lỗi thường gặp bên dưới.
Bước 4 — Thêm nhiều kịch bản
- Với cùng endpoint, thêm example
Out of stock - 409, đặt matching qua query như?scenario=out_of_stock. - Để ép mock trả đúng một example cụ thể bất kể matching, thêm header
x-mock-response-name: Out of stock - 409(hoặcx-mock-response-code: 409) vào request. Đây là "công tắc" cực hữu ích để test từng nhánh.
Bước 5 — Bàn giao cho frontend
- Chia sẻ mock URL (và API key nếu private) cho frontend.
- Hướng dẫn họ đặt
base_url = mock URLtrong môi trường dev của họ. - Ghi rõ trong tài liệu: đâu là example nào, dùng header/query nào để trigger kịch bản lỗi.
Lỗi thường gặp & mẹo
"No matching request" dù đã lưu example. Đây là lỗi số một. Nguyên nhân hay gặp: path không khớp chính xác (thừa/thiếu dấu /), method sai (example lưu là POST nhưng bạn gọi GET), hoặc query param bắt buộc bị lệch. Mẹo: mở example ra, kiểm tra dòng URL của request mẫu bên trong example, đảm bảo nó trùng path bạn đang gọi.
Quên rằng mock chỉ trả static. Nhiều người kỳ vọng mock "thông minh" tự tính toán. Không — mock chỉ trả lại thứ đã lưu. Nếu bạn muốn dữ liệu thay đổi, phải dùng biến dynamic như {{$randomInt}}, {{$isoTimestamp}} trong body example.
Header Content-Type bị thiếu. Nếu frontend parse JSON mà mock không trả Content-Type: application/json, có thể lỗi. Luôn set header này trong example response.
Mock lệch với contract thật (như tình huống 3). Mẹo phòng ngừa mạnh nhất: dùng chung một spec OpenAPI làm nguồn sự thật, sinh example từ đó, và review example mỗi lần backend đổi.
Ép kịch bản bằng header đặc biệt. Ghi nhớ ba header vàng: x-mock-response-name (chọn theo tên example), x-mock-response-code (chọn theo status), x-api-key (cho mock private). Bộ ba này giúp bạn điều khiển mock chính xác khi test.
Delay giả lập. Muốn mô phỏng API chậm để test loading state? Thêm header x-mock-response-delay: 2000 (mili giây). Rất hữu ích để test spinner/timeout của frontend.
Đừng dùng mock cho load test. Mock không phải để đo hiệu năng — đó là việc của JMeter/k6 (đề cập ở bài 30). Mock có giới hạn số lần gọi theo gói Postman.
Bài tập thực hành
- Tạo mock cơ bản: Tạo collection
Shop APIvới endpointGET /products/1. Lưu example trả200với body{"id":1,"name":"Áo thun","price":199000}. Tạo mock server và gọi thử tới mock URL, xác nhận nhận đúng body.
- Nhiều kịch bản: Thêm hai example cho
GET /products/999: một404{"error":"Không tìm thấy sản phẩm"}và một503{"error":"Hệ thống bảo trì"}. Dùng headerx-mock-response-codeđể lần lượt trigger từng response. Ghi lại cách bạn chuyển giữa chúng.
- Dynamic data: Sửa example
GET /ordersđể trả về{"order_id":"{{$guid}}","total":{{$randomInt}},"created_at":"{{$isoTimestamp}}"}. Gọi mock ba lần và kiểm tra rằng mỗi lần dữ liệu khác nhau.
- Mô phỏng độ trễ: Thêm
x-mock-response-delay: 3000và đo thời gian phản hồi trong tab Postman. Suy nghĩ: frontend sẽ hiển thị gì trong 3 giây đó?
- Tình huống team: Viết một đoạn ngắn (5–7 dòng) mô tả bạn sẽ dùng mock để tháo gỡ nút thắt frontend–backend trong một tính năng cụ thể của dự án bạn từng làm. Ghi rõ: contract là gì, các example nào, bàn giao thế nào.
Tóm tắt
- Mock server là API giả do Postman host, trả về examples bạn định nghĩa sẵn — giúp frontend, backend và QA làm việc song song thay vì chờ nhau.
- Mock sống nhờ examples, không phải request. Không có example khớp → lỗi
no matching request. - Phân biệt static mock (body cố định) và dynamic mock (dùng
{{$randomInt}},{{$guid}},{{$isoTimestamp}}để sinh dữ liệu ngẫu nhiên). - Ba header điều khiển vàng:
x-mock-response-name,x-mock-response-code,x-api-key; thêmx-mock-response-delayđể giả lập độ trễ. - Sức mạnh lớn nhất của mock: mô phỏng các nhánh lỗi/edge case khó tái tạo và buộc team thống nhất contract trước.
- Cạm bẫy chết người: mock lệch với contract thật tạo cảm giác an toàn giả. Luôn giữ example đồng bộ với API thật, lý tưởng là sinh từ một spec OpenAPI chung.
- Mock không thay thế load testing (JMeter/k6) và không phải monitor theo lịch — nó chỉ làm một việc và làm rất tốt: phục vụ response giả để phát triển song song.