Smart mock ช่วยสร้าง API ปลอมได้ภายในไม่กี่วินาที โดยอ่าน Schema ของ Endpoint แล้วส่งข้อมูลที่สมเหตุสมผลกลับมา เช่น อีเมลที่ดูสมจริง, timestamp ที่ใช้งานได้ และชื่อที่ไม่ใช่ xJ8kQ สำหรับงาน Frontend ส่วนใหญ่ Smart mock เพียงพอให้ทีมเริ่มพัฒนาได้โดยไม่ต้องรอ Backend
แต่เมื่อคุณต้องการให้ POST /login ส่งคืน 200 สำหรับผู้ใช้ที่รู้จักและ 401 สำหรับคนอื่น หรือให้ GET /orders/{id} ส่งคืนคำสั่งซื้อคนละสถานะตาม id รวมถึงบังคับ 500 เพื่อทดสอบ error handling — Smart mock อย่างเดียวไม่พอ เพราะมันส่งคืนรูปแบบเดียวต่อ Endpoint และไม่แตกแขนงตามคำขอ
Apidog แก้ปัญหานี้ด้วย 2 ฟีเจอร์:
- Mock expectations: กำหนด response แบบมีเงื่อนไขด้วยกฎ
- Mock scripts: เขียน JavaScript สำหรับตรรกะที่กฎทั่วไปทำไม่ได้
บทความนี้จะพาคุณตั้งค่าทั้งสองแบบ พร้อมอธิบายลำดับความสำคัญของ response เพื่อให้กฎที่กำหนดเองถูกเลือกก่อน Smart mock เสมอ หากยังไม่คุ้นกับพื้นฐาน ดู ภาพรวมการจำลอง API ได้ก่อน โดยเครื่องมือที่ใช้ตลอดบทความคือ Apidog และแนวทาง contract-first นี้สอดคล้องกับแนวคิดของ OpenAPI Initiative
การจำลองแบบมีเงื่อนไขคืออะไร
Mock แบบมีเงื่อนไขคือกฎลักษณะนี้:
เมื่อคำขอมีคุณสมบัติแบบนี้ ให้ส่ง response แบบนั้น
Apidog มีการตั้งค่า Mock อยู่ 2 ระดับ
ระดับฟิลด์ใน Schema
กำหนดค่าคงที่หรือใช้ expression ของ Faker.js เพื่อสร้างข้อมูลแบบไดนามิก เช่น ชื่อ อีเมล หรือวันที่ วิธีนี้ควบคุมค่าของฟิลด์ได้ แต่ยังเป็น response รูปแบบเดียวต่อ Endpoint-
ระดับ Mock expectation
สร้าง response เต็มรูปแบบที่มีเงื่อนไข, status code, headers และ response body ของตัวเอง เหมาะกับการแตกแขนง เช่น:- ส่ง response B เมื่อคำขอตรงกับเงื่อนไข A
- ส่ง
401เมื่อไม่มี header ที่ต้องการ - ส่ง order คนละสถานะตาม path parameter
ส่วนที่เหลือของบทความจะเน้นการใช้ Mock expectations และ Mock scripts ในงานจริง
เริ่มจากค่าไดนามิกระดับฟิลด์
ก่อนตั้งกฎแบบมีเงื่อนไข ควรรู้รูปแบบ expression ที่ใช้สร้างข้อมูลไดนามิกใน Schema ก่อน
ฟิลด์ string ใน Endpoint Schema สามารถใช้ Faker.js expression ในรูปแบบ:
{{$category.method}}
ตัวอย่าง response body:
{
"id": "{{$number.int(min=1000,max=9999)}}",
"customer": "{{$person.fullName}}",
"email": "{{$internet.email}}",
"product": "{{$commerce.productName}}",
"shippingAddress": "{{$location.streetAddress}}, {{$location.city}}",
"orderedAt": "{{$date.between(from='2024-01-01',to='2024-12-31',format='yyyy-MM-dd')}}"
}
คุณสามารถกำหนด parameter ให้เมธอดได้ เช่น:
-
{{$number.int(min=1000,max=9999)}}กำหนดช่วงตัวเลข -
{{$date.between(...)}}กำหนดช่วงวันและรูปแบบวันที่ - รวมข้อความคงที่กับหลาย expression ได้ในฟิลด์เดียว
หากต้องการข้อมูลเฉพาะภูมิภาค เช่น ชื่อ ที่อยู่ หรือเบอร์โทรศัพท์ตามประเทศ สามารถใช้ mock locale ได้ ดูรายการเมธอดเพิ่มเติมจาก เอกสารอ้างอิง Faker.js ใน Apidog
Smart mock ทำให้ข้อมูลเป็นไดนามิกได้ แต่ยังไม่สามารถเลือก response ตามเงื่อนไขของ request ได้ สำหรับกรณีนั้น ให้ใช้ expectations
ตัวอย่าง: POST /login ที่ส่งคืน 200 หรือ 401
สมมติว่า POST /login รับ JSON body นี้:
{
"username": "alice@example.com",
"password": "whatever"
}
เป้าหมายคือ:
- ผู้ใช้
alice@example.comได้200พร้อม token - ผู้ใช้อื่นได้
401
เปิดแท็บตั้งค่า Mock
ตำแหน่งการตั้งค่าขึ้นอยู่กับโหมดที่คุณใช้:
- ในโหมด DEBUG หรือ Request-first: เปิด Endpoint แล้วเลือกแท็บ Mock
- ในโหมด DESIGN หรือ Design-first: เปิด Endpoint แล้วเลือกแท็บ Advanced mock
ทั้งสองทางจะเปิดรายการ expectation เดียวกัน หากยังไม่มีโปรเจกต์ ให้ ดาวน์โหลด Apidog แล้วสร้างหรือนำเข้า Endpoint /login
สร้าง expectation สำหรับ login สำเร็จ
- คลิก New expectation
- ตั้งชื่อเป็น
login-success - เพิ่มเงื่อนไขแบบ Body parameter
- ระบุชื่อฟิลด์เป็น
username - ตั้งค่าให้เท่ากับ
alice@example.com - กำหนด Response data ดังนี้
{
"token": "mock-jwt-{{$string.uuid}}",
"user": {
"id": 4821,
"username": "alice@example.com",
"role": "member"
}
}
สำหรับ JSON body ให้ใช้ JSON path ในช่องชื่อ หากเป็น property ซ้อนกัน เช่น:
user.email
ค่า HTTP Status Code เริ่มต้นคือ 200 จึงไม่ต้องแก้ไขเพิ่มสำหรับกรณีสำเร็จ
สร้าง expectation สำหรับ login ล้มเหลว
สร้าง expectation อีกอัน:
- คลิก New expectation
- ตั้งชื่อเป็น
login-failure - ปล่อยเงื่อนไขว่างไว้ เพื่อให้เป็น catch-all
- กำหนด Response data
{
"error": "invalid_credentials",
"message": "Username or password is incorrect."
}
จากนั้น:
- เปิดแท็บ More
- ตั้งค่า HTTP Status Code เป็น
401
แท็บ More ยังใช้ตั้งค่าได้ เช่น:
- Response Delay หน่วยมิลลิวินาที
- response headers แบบกำหนดเอง
ตัวอย่างเช่น ตั้ง delay เป็น 400 ms เพื่อทดสอบว่า loading spinner ของ Frontend แสดงผลถูกต้องหรือไม่
ลำดับของ expectation มีผลโดยตรง
Apidog ประเมิน expectations จากบนลงล่าง และใช้กฎแรกที่ตรงกับ request
ดังนั้นต้องเรียงแบบนี้:
login-successlogin-failure
หากวาง login-failure ซึ่งไม่มีเงื่อนไขไว้ด้านบน มันจะจับทุก request และกรณี 200 จะไม่เกิดขึ้น
ทดสอบ mock URL ด้วย curl:
# known user -> 200 with a token
curl -X POST https://<your-mock-host>/login \
-H "Content-Type: application/json" \
-d '{"username":"alice@example.com","password":"whatever"}'
# anyone else -> 401
curl -X POST https://<your-mock-host>/login \
-H "Content-Type: application/json" \
-d '{"username":"stranger@example.com","password":"whatever"}'
ตัวอย่าง: response ต่างกันสำหรับ /orders/{id}
อีกกรณีที่พบบ่อยคือการแตกแขนงตาม path parameter เพื่อให้ Frontend แสดงผลทุกสถานะได้โดยไม่ต้องมี Backend จริง
ตัวอย่าง:
-
GET /orders/5001ส่งคืนคำสั่งซื้อที่จัดส่งแล้ว -
GET /orders/5002ส่งคืนคำสั่งซื้อที่ยกเลิกแล้ว -
GET /orders/<id อื่น>ส่งคืนคำสั่งซื้อ pending เป็น fallback
สร้าง expectation หนึ่งรายการต่อสถานะ
Expectation: order-shipped
เงื่อนไข:
Path Parameter id = 5001
Response data:
{
"id": 5001,
"status": "shipped",
"total": 129.9,
"trackingNumber": "1Z{{$string.alphanumeric(length=16)}}",
"shippedAt": "{{$date.recent(days=3,format='yyyy-MM-dd')}}"
}
Expectation: order-cancelled
เงื่อนไข:
Path Parameter id = 5002
Response data:
{
"id": 5002,
"status": "cancelled",
"total": 0,
"cancelledAt": "{{$date.recent(days=1,format='yyyy-MM-dd')}}",
"refundIssued": true
}
จากนั้นเพิ่ม expectation สุดท้ายที่ไม่มีเงื่อนไข เพื่อเป็น fallback สำหรับ ID อื่น
หลักการเรียงลำดับคือ:
- กฎเฉพาะเจาะจงที่สุด
- กฎเฉพาะเจาะจงรองลงมา
- catch-all ที่ไม่มีเงื่อนไข
คุณสามารถรวมหลายเงื่อนไขได้ เช่น ใช้ทั้ง Path parameter และ Header พร้อมกัน โดยทุกเงื่อนไขต้องเป็นจริง เพราะ Apidog ใช้ตรรกะ AND
เงื่อนไขที่ใช้ได้ไม่ได้จำกัดแค่ Body หรือ Path แต่ยังรองรับ:
- Query parameter
- Header parameter
- Cookie parameter
- IP address
บังคับ status code ของ error ตามต้องการ
คุณไม่จำเป็นต้องทำให้ Backend เสียจริงเพื่อทดสอบ error handling ของ Frontend
ตัวอย่างการบังคับ 500:
- สร้าง expectation ใหม่
- เพิ่มเงื่อนไข Header:
X-Mock-Scenario = server-error
- ตั้งค่า response body:
{
"error": "internal_error",
"requestId": "{{$string.uuid}}",
"message": "Something went wrong on our end. Please retry."
}
- เปิดแท็บ More
- ตั้งค่า HTTP Status Code เป็น
500
ตอนนี้ Endpoint เดิมจะตอบสนองแบบปกติเป็น 200 แต่จะส่ง 500 เมื่อ Client ส่ง header นี้:
curl https://<your-mock-host>/orders/5001 \
-H "X-Mock-Scenario: server-error"
ใช้แนวทางเดียวกันสำหรับสถานะอื่นได้ เช่น:
404 Not Found429 Too Many Requests503 Service Unavailable
สำหรับ 429 คุณสามารถเพิ่ม header Retry-After ได้จากแท็บ More
หากต้องการตรวจสอบ response เหล่านี้ใน automated tests ให้ดู API assertions
ในโปรเจกต์ที่ทำงานร่วมกัน คุณสามารถเปิดหรือปิด expectation แต่ละรายการแยกกันได้สำหรับ Local Mock และ Cloud Mock เช่น เปิดกฎ 500 เฉพาะ Local เพื่อไม่ให้รบกวนเพื่อนร่วมทีมที่ใช้ Cloud Mock
เมื่อกฎไม่พอ: Mock scripts
Expectations เป็น declarative: จับคู่เงื่อนไขแล้วส่ง response กลับ แต่ไม่เหมาะกับการคำนวณ
ใช้ Mock script เมื่อคุณต้องการ:
- คำนวณยอดรวมจากรายการสินค้าใน request
- สร้างค่าที่อ้างอิงจาก request body
- เปลี่ยนรูปแบบ response จากข้อมูลหลายส่วน
- สะท้อน header หรือข้อมูลบางส่วนจาก caller
Mock script คือ JavaScript ที่ทำงานกับ Mock response โดยตั้งค่าได้จาก Mock Script section ด้านล่างของแท็บ Mock
ตัวแปรหลักที่ใช้มี 2 ตัว:
-
$$.mockRequest: อ่าน request ขาเข้า -
$$.mockResponse: กำหนด response ขาออก
ตัวอย่าง script ที่คำนวณยอดคำสั่งซื้อและอ่านสกุลเงินจาก header:
const body = $$.mockRequest.body;
const items = body.items || [];
const subtotal = items.reduce((sum, item) => {
return sum + item.price * item.quantity;
}, 0);
const currency = $$.mockRequest.headers["x-currency"] || "USD";
$$.mockResponse.setCode(201);
$$.mockResponse.setBody({
orderId: Math.floor(Math.random() * 90000) + 10000,
currency: currency,
subtotal: subtotal,
tax: Number((subtotal * 0.08).toFixed(2)),
total: Number((subtotal * 1.08).toFixed(2))
});
เมธอดที่ใช้บ่อย ได้แก่:
$$.mockRequest.getParam(key);
$$.mockResponse.setBody(data);
$$.mockResponse.setCode(statusCode);
$$.mockResponse.setDelay(milliseconds);
$$.mockResponse.json(data);
นอกจากนี้ $$.mockResponse ยังเข้าถึง headers และ code ได้
ลำดับการทำงานคือ:
- Smart mock สร้าง response เริ่มต้นจาก Schema
- Script อ่าน
$$.mockRequestและ response ปัจจุบัน - Script ใช้ตรรกะของคุณ
- Script เรียก
setBody(),setCode(),setDelay()หรือกำหนด headers - Engine ส่ง response สุดท้ายกลับไป
หากต้องการต่อยอดด้วย Array methods หรือการคำนวณวันที่ ดู เอกสาร MDN JavaScript
ข้อควรจำ: Mock script ใช้ร่วมกับ expectation ไม่ได้
Mock scripts ทำงานกับ Smart mock เท่านั้น
Script จะไม่ทำงานเมื่อ:
- request ตรงกับ Mock expectation
- response ถูกเลือกจาก Response example
ดังนั้นเลือกใช้เพียงแนวทางเดียวต่อ Endpoint:
| ความต้องการ | วิธีที่ควรใช้ |
|---|---|
| แตกแขนงตาม Header, Body, Path หรือ Query | Mock expectations |
| ส่ง body และ status code ที่กำหนดไว้ล่วงหน้า | Mock expectations |
| คำนวณผลลัพธ์จาก request | Mock scripts |
| สร้าง response แบบไดนามิกจาก Schema | Smart mock หรือ Mock scripts |
Apidog เลือก response ตามลำดับใด
สำหรับทุก Mock request Apidog ทำงานตามลำดับนี้:
- ตรวจสอบ expectations จากบนลงล่าง
- expectation แรกที่มีเงื่อนไขตรงกันจะชนะและส่ง response ทันที
- หากไม่มี expectation ใดตรงกัน Apidog จะใช้ Mock method priority ที่ตั้งไว้ใน:
Project Settings → Feature Settings → Mock Settings
- Smart mock และ Mock script จะทำงานใน fallback layer นี้
สรุปเป็นกฎง่าย ๆ:
กฎเฉพาะเจาะจงมาก่อน ข้อมูลที่สร้างอัตโนมัติมาทีหลัง
จัดเรียง expectations จากเฉพาะเจาะจงที่สุดไปหาทั่วไปที่สุด และวาง catch-all ไว้ล่างสุดหากต้องการ fallback ที่ตายตัว
สำหรับแนวทางเลือกใช้ Mock แต่ละรูปแบบ ดู กรณีการใช้งานการจำลอง API
ข้อจำกัดที่ควรรู้ก่อนใช้งาน
มีข้อจำกัดสำคัญที่ควรตรวจสอบก่อนแก้ปัญหา Mock ที่ดูเหมือนไม่ทำงาน:
เงื่อนไข parameter ไม่รองรับ
{{variables}}
ตัวแปรระดับโปรเจกต์และ environment ของ Apidog ใช้ภายใน Mock expectations ไม่ได้ ให้ใช้ค่า literalเงื่อนไข Body parameter รองรับ JSON เท่านั้น
สำหรับ JSON body ต้องระบุ property ด้วย JSON pathรูปแบบ request body ต้องตรงกับ API spec
หาก Endpoint ใช้form-dataคุณต้องกำหนดเงื่อนไขเป็นform-dataไม่ใช่ JSONMock scripts ไม่มี logging
ใช้pmไม่ได้ เพราะ runtime ต่างจาก Test scripts และใช้ตัวแปร Apidog ไม่ได้Local Mock และ Cloud Mock ต่างกันในด้านการเปิด/ปิด expectation ต่อ environment
ไม่ใช่ข้อจำกัดการเข้าถึงแบบ paywall
ทำให้เวิร์กโฟลว์เป็นอัตโนมัติด้วย Apidog CLI
Mock ใน Apidog ถูกจัดการผ่าน GUI และ Cloud Mock Engine ให้บริการ Endpoint จาก Local และ Cloud mock URL โดยไม่มีคำสั่ง CLI สำหรับเปิด Mock server โดยตรง
แต่ Apidog CLI ช่วยจัดการทรัพยากรที่ Mock ใช้เป็นฐานได้
Mock response ถูกสร้างจาก Endpoint Schema ดังนั้นคุณภาพของ Mock จึงขึ้นอยู่กับความถูกต้องของ API spec คุณสามารถใช้ CLI และ AI Coding Agents เช่น Cursor, Claude Code, Trae หรือ Codex เพื่อสร้างและอัปเดต Endpoint กับ Schema ในโปรเจกต์ได้
เมื่อ Frontend พัฒนาด้วย Mock แล้ว คุณสามารถรัน test scenario แบบ headless ใน CI เพื่อยืนยันว่า Backend จริงยังตรงตาม contract เดียวกัน:
apidog run -t <scenario_id> -e <env_id> -r cli
คำสั่งนี้จะรัน test scenario และรายงานผลลัพธ์ ช่วยให้ Mock และการตรวจสอบ Backend อ้างอิงแหล่งข้อมูลความจริงเดียวกัน
ดูรายละเอียดเพิ่มเติมได้ที่:
คำถามที่พบบ่อย
ทำไม expectation ถูกละเว้น ทั้งที่เงื่อนไขดูถูกต้อง
ตรวจสอบ 2 จุดก่อน:
ลำดับ expectation
กฎถูกประเมินจากบนลงล่าง กฎ catch-all ที่วางไว้ด้านบนจะจับทุก requestรูปแบบ request body
JSON ต้องใช้ JSON path และ Endpoint ที่ใช้ form-data ต้องกำหนดเงื่อนไขเป็น form-data
อ่านพื้นฐานเพิ่มเติมได้จาก ภาพรวมการจำลอง API
ใช้ Mock script และ Mock expectation กับ response เดียวกันได้หรือไม่
ไม่ได้
Mock script ทำงานกับ Smart mock เท่านั้น และจะถูกข้ามทันทีหาก expectation ตรงกับ request ใช้ expectations สำหรับ response แบบอิงกฎ และใช้ scripts สำหรับ output ที่ต้องคำนวณ
จะส่ง 401 หรือ 500 โดยไม่กระทบ 200 เริ่มต้นได้อย่างไร
สร้าง expectation เฉพาะที่มีเงื่อนไขควบคุมได้จาก Client เช่น header:
X-Mock-Scenario = server-error
จากนั้นตั้ง HTTP Status Code ในแท็บ More response ปกติยังคงเป็น 200 และ error จะเกิดขึ้นเฉพาะเมื่อ request ตรงกับเงื่อนไข
เงื่อนไขใช้ environment variables ได้หรือไม่
ไม่ได้
Mock expectations ไม่รองรับตัวแปรรูปแบบ {{variable}} ให้ใช้ค่า literal ในเงื่อนไข
ถ้าไม่มี expectation ใดตรงกันจะเกิดอะไรขึ้น
Apidog จะ fallback ไปยัง Mock method priority ใน:
Project Settings → Feature Settings → Mock Settings
จากนั้น Smart mock จะสร้าง response จาก Schema หากต้องการ fallback ที่แน่นอน ให้เพิ่ม expectation แบบไม่มีเงื่อนไขไว้ล่างสุด
สรุป
ใช้ Smart mock สำหรับข้อมูลทั่วไปที่สร้างจาก Schema และใช้ Mock expectations สำหรับ response ที่ต้องแตกแขนงตามเงื่อนไข เช่น:
-
200สำหรับผู้ใช้ที่รู้จัก และ401สำหรับคนอื่น - order response ที่เปลี่ยนตาม
idหรือสถานะ -
500,404,429หรือ503สำหรับทดสอบ error handling
ใช้ Mock script เมื่อคุณต้องการ response ที่คำนวณจาก request และจำไว้ว่า script ทำงานกับ Smart mock เท่านั้น ไม่ทำงานร่วมกับ expectation
เรียง expectation จากกฎเฉพาะเจาะจงไปหากฎทั่วไป แล้วให้ Smart mock เป็น fallback คุณจะได้ Mock API ที่มีพฤติกรรมใกล้เคียง Backend จริงมากขึ้น
ดาวน์โหลด Apidog เพื่อสร้าง conditional mock แรกของคุณ




Top comments (0)