Patch ยังไงให้อ่านรู้เรื่อง
สิ่งหนึ่งที่เราจะเจอหลังจากเขียน Unit Test มาได้ซักพักคือ มันจะมีบางอย่างที่เราควบคุมมันไม่ได้ครับ บางอย่างนั้นอาจจะเป็นไปได้ตั้งแต่ ค่าสุ่ม, เวลา, การอ่านเขียนไฟล์, การแก้ไข Database อะไรอย่างนี้เป็นต้น
พอเรามาเจออะไรพวกนี้ มันจะเกิดคำถามขึ้นมาทันทีว่า แล้วเราจะเทสมันยังไง ถ้ามันเปลี่ยนตลอดเวลา คำตอบของคำถามนั้นก็คือ เราต้อง Mock มันครับ ซึ่ง Python มี standard library ไว้จัดการเรื่องนี้ครับคือ unittest.mock.patch
Patch นั้นมีหลายท่า ก่อนหน้านี้ผมเคยเล่าให้ฟังบางส่วนแล้วว่าเราจะจัดการกับการ Patch หลายๆ module ยังไง ซึ่งใช้ ExitStack() มาช่วยในการจัดการ context สนใจไปอ่านต่อได้ที่นี่ครับ
แต่จริงๆ เราสามารถใช้ patch ได้ถึง 3 แบบเลย แล้วแต่สถานการณ์ครับ
patch decorator
แบบแรกคือ ใช้เป็น decorator ครับแบบนี้จะเหมาะกับ การที่เรา patch ฟังก์ชั่นจำนวนน้อยๆ ซึ่งพอมันน้อยเนี่ยมันจะยังไม่รบกวน test function signature มาก ทำให้เรา ยังพออ่านได้อยู่ว่า Test Case นั้นชื่ออะไร
patch context
แบบที่สอง น่าจะเคยเห็นมาจาก Tricks ข้างบนแล้วนะครับ คือเราใช้ภายใต้ context manager แทน แบบนี้ทำให้เราไม่ต้องมี decorator มากวนใจตรง function signature แล้วครับ ตัว patch จะถูกใช้ใน test function เลย แต่ข้อเสียคือ เราก็จะเสีย indent ไปนิดหน่อยตอนเราสั่งรัน function ที่เราจะเทส
patch manually
แบบสุดท้าย คือเราจะสั่ง patch เองครับผ่าน method start() และหยุด patch ผ่าน stop() พอเราสั่ง patch แบบนี้แล้ว มันเปิดโอกาสให้เราทำอะไรได้หลายๆ อย่างมากเช่น เรา patch ไว้ตั้งแต่ setUp เลย ถ้าฟังก์ชั่นนี้ต้อง patch ทุก TestCase ซึ่งจะช่วยลด Duplication ของ patch ใน code ไปได้ หรือเราอยากให้ TestCase เรามี indent น้อยๆ ก็จะช่วยได้เหมือนกัน
แต่พลังที่ยิ่งใหญ่มาพร้อมกับความรับผิดชอบที่ใหญ่ยิ่งครับ วิธีนี้สำคัญสุดเลยคือ ต้องอย่าลืมหยุด patch ครับ จะสังเกตุว่า ตอนเราใช้ decorator หรือ context manager เราไม่เคยต้องกังวลเรื่องนี้เลย เป็นเพราะว่าพอเราใช้สองอย่างนั้น พอออกจาก context มันจะหยุด path ให้เราอัตโนมัติครับ
ขอสรุปสั้นๆ อีกทีละกันว่าเราควรควรใช้ Patch ท่าไหนตอนไหน
- patch decorator ใช้เวลาที่เรา patch แค่หนึ่งฟังก์ชั่น
- patch as context manager ใช้เวลาที่เราจะ patch หลายๆ ฟังก์ชั่น
- patch manually start / stop ใช้เวลาต้อง patch เหมือนๆ กันทุกฟังก์ชั่นใน Test Suite หรือลดความซ้ำซ้อนของโค้ด
เป็นยังไงกันบ้างครับ การจะ Mock นี่ไม่ใช่เรื่องเล็กๆ เลย ข้อเสียของ patch ของ Python อีกอย่างนึงคือ Official Document อ่านยากมากครับ กว่าจะเข้าใจวิธีใช้ ต้องบอกว่าเทคนิคนี้ผมก็อ่านๆ มาจากหลายๆ Blog เหมือนกันครับ ใครสนใจศึกษาเพิ่มเติมก็ลองดูได้ตามลิ้งข้างล่างเลยครับ
Reference
Original post at: https://medium.com/pythonbycow/patch-ยังไงให้อ่านรู้เรื่อง-8d504b01b1ec