Vitest · Mocks และ Spies
`vi.restoreAllMocks()`
คืน implementation เดิมหลังใช้ spy เพื่อไม่ให้ test อื่นได้รับผลกระทบ
คืน implementation เดิมหลังใช้ spy
vi.restoreAllMocks() คืน implementation เดิมของ spy ทั้งหมดที่สร้างด้วย vi.spyOn ใน test context การ restore ทำให้ object กลับสู่สภาพก่อนเริ่มทดสอบ และป้องกันไม่ให้ test ถัดไปใช้ spy หรือ implementation ที่ test ก่อนหน้าเปลี่ยนไว้
วาง restore ใน afterEach เพื่อให้ทุก test ที่สร้าง spy ได้ cleanup แบบสม่ำเสมอ
กฎสำคัญ
restore คืน implementation
restoreAllMocks ไม่ใช่แค่ล้างจำนวน call แต่คืน method เดิมที่ spy ไปแทนไว้
วาง cleanup ใกล้ lifecycle
afterEach ทำให้กติกา cleanup ถูกบังคับใช้หลังทุก test ใน scope นั้น
restore ไม่ได้แก้ design boundary
ยังต้องเลือกก่อนว่า dependency ใดควรถูก spy และ interaction ใดเป็น contract
จะเกิดอะไรถ้าไม่ restore
ลองนึกถึง object calculator ที่ถูก spy ใน test แรก ถ้า spy ถูกทิ้งไว้ method ของ object จะยังมี wrapper ที่บันทึกการเรียกหรือ implementation ที่ถูกแทนอยู่ test ถัดไปจึงอาจรับสภาพแวดล้อมที่ไม่ใช่ของจริง
restore เป็นการคืน implementation ของ spy ไม่ใช่การซ่อน failure หรือการล้าง assertion ของ test แรก
วาง cleanup ใกล้จุดที่สร้าง side effect
ถ้ามีหลาย test ที่อาจสร้าง spy ให้ใช้ afterEach เป็นกติกากลาง เพื่อไม่ต้องหวังว่าผู้เขียนทุกข้อจะจำ cleanup เอง
clear, reset และ restore ไม่ใช่คำเดียวกัน
| แนวคิด | ผลหลัก |
|---|---|
| clear call history | ล้างข้อมูลว่าเคยถูกเรียกกี่ครั้ง แต่ implementation อาจยังถูกแทน |
| reset mock behavior | reset behavior ของ mock ตาม API ที่ใช้ |
| restore all mocks | คืน implementation เดิมของ spy |
บทนี้โฟกัส restore spy
ยังไม่ขยายไปสู่ mock lifecycle ขั้นสูง ให้จำหลักการก่อนว่า test ต้องคืนสภาพแวดล้อมที่ตัวเองเปลี่ยน
แบบฝึก: ทำ cleanup ให้ครบ
เพิ่ม afterEach ให้ test ที่ใช้ calculator spy ไม่ทิ้ง implementation ที่ถูกแทนไว้
งานที่ต้องทำ
- import afterEach และ vi
- เรียก vi.restoreAllMocks ใน afterEach
- คง assertion ที่ตรวจผลลัพธ์และ call count ไว้
ลองทำด้วยตัวเองก่อน แล้วค่อยเปิดเฉลยเพื่อเทียบแนวคิดและรายละเอียด