ผมเคยสับสนมานานว่าเมื่อไหร่ควรจะ mock และคนที่เคลียร์ปัญหาคาใจผมก็คือเจ้านายผมเอง
เขาบอกโดยสรุปว่า
mock ในส่วนที่เราไม่พิจารณา
เช่นใน controller เราจะพิจารณาที่ logic ของ controller เท่านั้น ในส่วนของ model ที่เราเรียกใช้งานก็ไม่ต้องสนว่าจริงๆ แล้วมันทำงานยังไง เราเลย mock ที่ model ไปเลย ส่วนจะ lock การคืนค่าหรือตัวแปรต่างๆ ก็ stub เอา ส่วน logic ต่างๆ ก็
กระโดนมาส่วน model บ้าง ในส่วนของ model ที่เรา mock ใน controller ไปแล้ว เราควรจะมา test อีกที ทีนี้เราพิจารณา logic ใน model ซึ่งโดยมากแล้วก็ไม่รู้จะ mock อะไร เพราะมันล้วนซึ่งต้องทำงานตาม code ที่เขียนไว้จริงๆ(ดูคล้ายๆ กับ unit test)
มาดูตัวอย่างกัน
ตัวอย่าง 1
อันนี้เป็นตัวอย่างจาก scaffold
สิ่งที่ mock ล้วนซึ่งเป็น model ทั้งนั้น เริ่มจาก before ด้วยการ mock ไปก่อนแล้วตามด้วย stub
ที่ต้อง stub เพราะต้องจำลองผล เพราะเรา mock model มาอีกทีนึง มันจึงไม่แตะ code ของ model จริงๆ
ยังมีส่วนของการ render/redirect ใน controller อีก แต่อันนี้ เราจำเป็นต้องวัดผล(พิจารณา)มันจริงๆ เลยไม่จำเป็นต้อง mock ในส่วนของ render/redirect
ตัวอย่าง 2 จากLuke Redpath
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | describe "A user (in general)" do setup do @user = User.new end it "should be invalid without a username" do @user.email = 'joe@bloggs.com' @user.should_not_be_valid @user.errors.on(:username).should_equal "is required" @user.username = 'someusername' @user.should_be_valid end it "should be invalid without an email" do @user.username = 'joebloggs' @user.should_not_be_valid @user.errors.on(:email).should_equal "is required" @user.email = 'joe@bloggs.com' @user.should_be_valid end end |
ตัวอย่างนี้ไม่มี mock สักตัว เพราะต้องการ test logic ที่มันควรจะเป็นจริงๆ
แต่ถ้า model มีการทำงานร่วมกับ model ตัวอื่น อันนี้ก็น่าจะ mock เป็นต้น