Vitest · Assertions พื้นฐาน
`.toEqual()`
ตรวจ object และ array ด้วย deep equality
toEqual()
toEqual() ใช้เปรียบเทียบค่าใน object หรือ array แบบ deep equality คือเดินดู property และสมาชิกด้านในว่ามีโครงสร้างและค่าเท่ากัน แม้ object ที่นำมาเปรียบเทียบจะเป็นคนละ reference
object ที่สร้างขึ้นใหม่ยังผ่านได้ เพราะ toEqual สนใจโครงสร้างและค่า
กฎสำคัญ
สนใจโครงสร้าง ไม่ใช่ reference
ใช้ toEqual เมื่อ contract พูดถึงข้อมูลที่ควรมีค่าเท่ากัน ไม่ได้พูดว่าต้องคืน object ก้อนเดิม
ให้ matcher ตรงกับคำถาม
เลือกวิธีตรวจจาก behavior ที่ต้องการ ไม่เลือกจากชื่อที่ดูคุ้นหรือสั้นที่สุด
แกะตัวอย่างทีละขั้น
อย่าอ่าน matcher เป็นคำสั่งเดี่ยว ให้ตามเส้นทางของข้อมูลจาก input ไป actual แล้วดูว่า matcher ตัดสิน actual อย่างไร ตารางนี้แยกสามช่วงของตัวอย่างออกจากกันเพื่อช่วยให้เริ่มอ่านได้ทีละส่วน
| ขั้น | สิ่งที่เกิดขึ้น |
|---|---|
| เตรียมข้อมูล | สร้าง Task ที่ยังไม่ completed |
| เรียก behavior | ส่ง Task เข้า `completeTask` แล้วได้ object ผลลัพธ์กลับมา |
| เทียบโครงสร้าง | `.toEqual({...})` ไล่ดู property และค่าด้านใน ไม่บังคับ reference เดิม |
ถ้าแก้ค่าตั้งต้นในตัวอย่าง ให้ถามต่อว่า toEqual() ยังตรงกับคำถามเดิมหรือไม่ ตัวอย่างที่ดีไม่ได้แค่ทำให้ test ผ่าน แต่ทำให้เราเข้าใจว่ากำลังพิสูจน์ behavior ใด
toBe กับ toEqual ต่างกันตรงไหน
| สถานการณ์ | วิธีคิด |
|---|---|
| สอง object มี property และค่าเหมือนกัน แต่สร้างคนละก้อน | toEqual ผ่าน, toBe ไม่ผ่าน |
| ต้องการตรวจ primitive หนึ่งค่า | toBe อ่านง่ายและตรง intent กว่า |
| ต้องการตรวจ array หรือ object ทั้งก้อน | toEqual เหมาะกับ deep equality |
อย่าตรวจเกิน contract
ถ้า requirement สนใจเฉพาะ property หรือ state หนึ่งอย่าง ให้ตรวจเท่านั้น การ assert รายละเอียดที่ไม่ใช่สัญญาจะทำให้ test เปราะโดยไม่เพิ่มความมั่นใจ
แบบฝึก: เลือกและเขียน matcher
ตรวจผลลัพธ์ completeTask เป็น object ครบทั้งก้อน
งานที่ต้องทำ
- เตรียม Task ที่ completed เป็น false
- เรียก completeTask
- เปรียบเทียบผลลัพธ์กับ object ที่ completed เป็น true ด้วย toEqual
ลองทำด้วยตัวเองก่อน แล้วค่อยเปิดเฉลยเพื่อเทียบแนวคิดและรายละเอียด