ในการ Test อ็อบเจกต์หรือคลาสใดๆ ด้วย Rspec รูปแบบหรือฟอร์มที่เป็นพื้นฐานที่สุดสำหรับทดสอบ incomming message (หรือ instance เมธอด) ก็คือการใช้ expect(object) to respond_to(something) รูปแบบนี้มีความหมายชัดเจนในตัวอยู่แล้ว แต่ถ้าหากเราจะต้อง test เมธอดหลายๆ เมธอด การใช้ฟอร์มแบบนี้อาจก่อให้เกิดโค้ดที่ซ้ำกันโดยไม่จำเป็นและที่สำคัญมันอาจทำให้เราตาลายได้
วิธีแก้ ง่ายมาก ให้กำหนดอ็อบเจกต์เบื้องต้น (default object) ให้กับ rspec เพื่อทำการทดสอบในขอบเขตนั้นๆ โดยใช้ subject และใช้ should เพื่ออ้างถึง default object ดังกล่าว
สมมติว่า test โค้ดของเรามักจะมีหน้าตาประมาณนี้
describe MyClass do
before { @my_object = MyClass.new(color: "Red", weight: 60) }
it "should respond to 'color'" do
expect(@my_object).to respond_to(:color)
end
it "should respond to 'weight'" do
expect(@my_object).to respond_to(:weight)
end
end
โค้ดข้างต้นสามารถลดรูปให้สั้นลงและอ่านง่ายขึ้นได้ โดยใช้ subject และ should เข้ามาช่วย ดังนี้
describe MyClass do
before { @my_object = MyClass.new(color: "Red", weight: 60) }
subject { @my_onject }
it { should respond_to(:color) }
it { should respond_to(:weight) }
end
เมธอด subject {@my_object} เป็นตัวหนดให้ @my_object กลายเป็น default object ที่จะถูกนำมารัน test ด้วยเมธอดต่างๆ ของ rspec ส่วนเมธอด should จะทำหน้าที่ตรวจสอบเงื่อนไขว่าเป็นจริงหรือไม่
จากตัวอย่างนี้ respond_to(:color) จะมีความหมายเดียวกับการใช้เมธอด respond_to? (จากคลาส Object ใน Ruby) ซึ่งจะคืนค่า true ออกมา ทำให้ผ่านเงื่อนไขของการ test ในที่สุด
ลองดูผลลัพธ์ที่เกิดจากเมธอด respond_to? กัน
>> class MyClass
>> def color
>> end
>> end
=> nil
>> obj = MyClass
=> MyClass
>> obj.respond_to?("color")
=> true
>> obj.respond_to?("other")
=> false