มัน คือ เทคนิคการเขียนโปรแกรมที่ใช้สร้าง "ตัวแทน" ของ object จริง เพื่อใช้งานในการเขียน unit test ให้นึกภาพเป็น "สตั้นแมน" ในภาพยนตร์ก็ได้ ที่เข้ามาแทนพระเอกในฉากเสี่ยงๆ Test double ก็เหมือนกัน มันจะทำหน้าที่เป็นตัวแทนของ object ที่เราไม่ต้องการที่จะให้มันทำงานจริงๆ
ประเภทของ Test Double
Test Double มีหลายประเภท แต่ละประเภทมีวัตถุประสงค์การใช้งานที่แตกต่างกัน ดังนี้
Mock
เป็นตัวแทน object จริงที่มีความสามารถใกล้เคียงกับ object จริงมากที่สุด เพราะว่ามันจะใช้เมื่อต้องการตรวจสอบพฤติกรรมการทำงาน (Behavior verification) มันยังสามารถกำหนดค่า expectation ของ method ต่างๆ ได้ เพื่อตรวจสอบว่า code โต้ตอบกับ object จริงอย่างถูกต้องหรือไม่
โดยทั่วไปแล้ว เรามักจะใช้คำว่า mock ในการเรียกการ test double ตัวอื่นๆ ด้วย (Every thing is mock 555+)
Stub
เรียกอีกอย่างหนึ่งว่า stub out เป็นตัวแทน object จริงที่มีการกำหนดพฤติกรรมที่กำหนดไว้ล่วงหน้า (predefined behavior) แต่จะเน้นไปที่การกำหนดค่า return value ของ method นั้นๆ
มักใช้เพื่อทดสอบ logic ของ code โดยไม่ต้องสนใจการทำงานของ object จริง เป็นเหมือนกับการกำหนดสถานะของค่าที่ต้องการว่าต้องการให้ object นั้นทำงานด้วยสถานะอะไร ต้องการให้ ค่าที่ส่งกลับมา ถูก หรือ ผิด ตามที่ต้องการทดสอบ เราอาจจะเรียกว่าเป็นการทดสอบเรื่อง State verification นั่นเอง
Dummy
เป็นตัวแทน object จริง ที่เรียบง่ายที่สุด โดยที่เราจะสร้างมันเป็น class หรือ method เปล่าๆ ขึ้นมาตัวหนึ่งที่ข้างในไม่มีอะไรเลย ไม่มีความสามารถอะไรเลย
เราจะใช้ dummy เพื่อให้ code ของเรา compile ผ่านเท่านั้นเอง หรือเอามาใช้เพื่อทดสอบว่า code ที่เราเขียนนั้นได้ไปเรียกใช้ object นั้นจริงๆ
Spy
เป็นตัวแทน object จริง ที่สามารถบันทึกการเรียกใช้ method ต่างๆ ได้ เราจะใช้เพื่อตรวจสอบว่า code โต้ตอบกับ object จริงกันอย่างไร มันทำงานได้ถูกต้องไหม (Exclusive behavior verification) เช่น มันเรียก method นั้น กี่ครั้ง
Spy มันมีข้อเสียหนึ่งที่เห็นได้ชัดเลยคือ code ของการทดสอบมันจะผูกติดกับ code จริงมากจนเกินไป ทำให้บางครั้งเมื่อมีการแก้ไข code จะกระทบต่อการทดสอบเป็นอย่างมาก
Fake
เป็นตัวแทนของ object จริง ที่เหมือนจริงมากๆ จนแทบแยกไม่ออก ใกล้เคียงของจริงสุดๆ โดยมีวัตถุประสงค์ เพื่อจัดการกับการทำงานบางอย่างที่ไม่สามารถไปทดสอบจริงบน production ได้ เช่น Memory, Database, AWS Services เป็นต้น
ทั้งหมดนี้เป็นประเภทของ test double ซึ่งมีการใช้งานที่ต่างกันบ้าง และใกล้ๆ กันบ้างในบางตัว และที่เจอบ่อยๆ เลย คือ แต่ละ library อาจจะเรียกหรือการทำงานบางอย่างที่เหมือนๆ กัน ที่เจอบ่อยๆ ก็พวก stub mock และ spy ที่หลายๆ ตัวมันแทบจะทำงานเหมือนกันอยู่แล้ว
แต่ทั้งนี้ทั้งนั้น ให้คิดไว้เสมอว่า เมื่อไหร่ก็ตามที่การทดสอบของเรามันเริ่มมีความยุ่งยากในการเตรียมการในการทดสอบ หรือมีการผูกกันหรือยุ่งเหยิงกันเกินไป เราอาจจะเขียน code นั้นให้ยากต่อการทดสอบเอง
เพราะฉนั้นหากเราต้องการให้ code ทดสอบง่าย จะต้องทำให้มันมีการทำงานในแต่ละส่วนที่ชัดเจน ไม่ผูกมันกันแน่นเกินไป (Loose coupling) และต้องเป็นอิสระต่อกันให้ได้เยอะที่สุด (Isolation)