Inside my tests I try and keep everything I need inside the test, rather than depending on too many fixtures. That way I ensure they’re as readable as possible, and more importantly, obvious.
But, take the following example:
def test_total_is_due_now_if_return_is_less_than_14_days booking = Booking.new( :customer => customers(:valerie), :collect_at => 1.day.from_now.to_date, :return_at => 13.days.from_now.to_date, :boxes => 2, :collection_address => addresses(:one)) assert_equal Date.today.to_s, booking.final_payment_due_date.to_senddef test_payment_due_14_days_from_now booking = Booking.new( :customer => customers(:valerie), :collect_at => 1.day.from_now.to_date, :return_at => 20.days.from_now.to_date, :boxes => 2, :collection_address => addresses(:one)) assert_equal 6.days.from_now.to_date.to_s, booking.final_payment_due_date.to_send
Well, everything’s in the test, but there’s a fair bit of duplication. What would be nicer, is to take the prototype booking above and just override certain values.
Instead we might write something like
def test_total_is_due_now_if_return_is_less_than_14_days booking = new_booking_with(:return_at => 13.days.from_now.to_date) assert_equal Date.today.to_s, booking.final_payment_due_date.to_senddef test_payment_due_14_days_from_now booking = new_booking_with(:return_at => 20.days.from_now.to_date) assert_equal 6.days.from_now.to_date.to_s, booking.final_payment_due_date.to_send privatedef new_booking_with(args) Booking.new(args.reverse_merge({ :customer => customers(:valerie), :collect_at => 1.day.from_now.to_date, :return_at => 15.days.from_now.to_date, :boxes => 2, :collection_address => addresses(:one) }))end
Much nicer (to me anyway), particularly once you start adding more and more tests (and especially validation related ones).