PlusMagi's Blog By Pitt Phunsanit Backend PHP: การทำ Mocking Object เพื่อแยกส่วนทดสอบ (Test Isolation)

PHP: การทำ Mocking Object เพื่อแยกส่วนทดสอบ (Test Isolation)

ในการพัฒนาซอฟต์แวร์ระดับองค์กร โค้ดของเราแทบจะไม่เคยทำงานในสุญญากาศ (Vacuum) เลย มันต้องพึ่งพา (Depend) ส่วนประกอบภายนอกจำนวนมาก ไม่ว่าจะเป็นการเชื่อมต่อฐานข้อมูล (Database), การเรียกใช้บริการผ่าน API ของ Third-party, หรือแม้แต่ระบบไฟล์ (File System) ความซับซ้อนเหล่านี้ทำให้การเขียน Unit Test แบบดั้งเดิมเป็นเรื่องที่ยากและไม่น่าเชื่อถือ

Mocking Object คืออะไร และทำไมต้องใช้?

Mocking Object คือเทคนิคขั้นสูงในการทดสอบซอฟต์แวร์ (Testing Technique) ที่เราใช้สร้าง “วัตถุจำลอง” หรือ “ตัวปลอม” ขึ้นมาแทนที่ Dependency ภายนอกที่เราไม่ต้องการให้มันทำงานจริง ๆ ในระหว่างการรัน Unit Test วัตถุเหล่านี้จะทำหน้าที่เสมือนว่าพวกมันคือของจริง แต่เราสามารถควบคุมพฤติกรรม (Behavior) ของมันได้อย่างสมบูรณ์แบบ

ปัญหาหลักที่ต้องแก้ไข (The Problem) คือการที่ Unit Test ของเราถูกผูกติดกับสภาพแวดล้อมภายนอก (เช่น DB Down, API ล่ม) ทำให้แม้ว่าตรรกะ (Logic) ในคลาสของเราจะถูกต้อง แต่ Test ก็ล้มเหลวด้วยเหตุผลที่ไม่เกี่ยวข้อง การใช้ Mocking จึงช่วยให้เราสามารถ Test Isolation ได้อย่างแท้จริง คือการทดสอบเพียงส่วนที่เราต้องการเท่านั้น

การประยุกต์ใช้ Mocking ใน PHP กับ PostgreSQL

สมมติว่าเรามี Service Class ใน PHP ที่ต้องดึงข้อมูลผู้ใช้จากฐานข้อมูล PostgreSQL การรัน Test นี้โดยตรงจะทำให้ทุกครั้งที่รัน Test ต้องมีการเชื่อมต่อฐานข้อมูลจริง ซึ่งช้าและเสี่ยงต่อความผิดพลาด

ด้วย Mocking เราจะทำการจำลอง (Mock) Connection หรือ Repository Layer ที่ทำหน้าที่เชื่อมต่อ PostgreSQL แทนการเชื่อมต่อจริง เมื่อเรา Mock แล้ว เราสามารถกำหนดได้ว่าเมื่อโค้ดของเราเรียกใช้เมธอด fetch_user_by_id(1) ตัว Mock Object จะต้องส่งข้อมูลจำลอง (Mock Data) กลับมาทันที โดยไม่ต้องแตะต้องฐานข้อมูลจริงเลยแม้แต่น้อย

SQL

-- Scenario: Mocking the database result set for a user ID 1. </code>
-- แทนที่จะรันคำสั่งจริงที่ต้องใช้เวลาและทรัพยากร
-- เรากำหนดให้ Mock Object ส่งผลลัพธ์นี้กลับมาทันที

SELECT
    1 AS user_id,
    'John Doe' AS full_name,
    '[email protected]' AS email
UNION ALL
SELECT
    2,
    'Jane Smith',
    '[email protected]'
; 

-- ในการทดสอบจริง PHPUnit จะ Mock การเรียกใช้ PDO/Doctrine เพื่อให้ได้ผลลัพธ์ชุดนี้โดยไม่ต้องเชื่อมต่อจริง

ข้อดีของการใช้ Mocking ในการทดสอบ

  • ความเร็ว (Speed): Test รันได้เร็วมาก เพราะไม่ต้องรอการ I/O จากภายนอก
  • ความน่าเชื่อถือ (Reliability): Test ไม่ล้มเหลวเพราะสภาพแวดล้อมภายนอก
  • ความชัดเจน (Focus): เราสามารถโฟกัสการทดสอบไปที่ตรรกะ (Business Logic) ของ PHP Class ได้อย่างเต็มที่

บทสรุป

การทำ Mocking Object ไม่ใช่แค่เทคนิคเสริม แต่เป็นทักษะสำคัญที่ Senior Developer ทุกคนต้องรู้ การใช้ Mocking อย่างถูกต้องจะช่วยให้ Unit Test ของเรามีความรวดเร็ว เชื่อถือได้ และเป็นอิสระจาก Dependency ภายนอก ทำให้การบำรุงรักษาโค้ดในระยะยาวเป็นเรื่องที่ง่ายและมีประสิทธิภาพอย่างยิ่ง

Exit mobile version