Rails Forum
Rails Work - the best place to post and find great Ruby on Rails jobs.
Username
Password

You are not logged in.

New Posts in this thread
  • Index
  •  » Tutorials
  •  » Test Helper: Clean, Custom Assertion Messages

#1 2006-09-28 16:42:05

ryanb
Moderator
Registered: 2006-06-14
Posts: 6323
Website

Test Helper: Clean, Custom Assertion Messages

In the previous article we ended up with this custom assertion:


Code :  ruby - fold - unfold
  1. def assert_invalid_value(model_class, attribute, value)
  2.   if value.kind_of? Array
  3.     value.each { |v| assert_invalid_value model_class, attribute, v }
  4.   else
  5.     record = model_class.new(attribute => value)
  6.     assert !record.valid?, "#{model_class} expected to be invalid when #{attribute} is #{value}"
  7.     assert record.errors.invalid?(attribute), "#{attribute} expected to be invalid when set to #{value}"
  8.   end
  9. end 
This works fine, but when the assertion fails we get this extra "<false> is not true" message at the end. Fore example:


Code :   - fold - unfold
  1. quantity expected to be invalid when set to -1.
  2. <false> is not true.
This second message is being generated by the call to "assert":


Code :  ruby - fold - unfold
  1. assert record.errors.invalid?(attribute), "#{attribute} expected to be invalid when set to #{value}" 
While checking out the Test::Unit documentation to see if there's some way to suppress this message, I noticed there's another method called assert_block which all assertions are based upon. Hey! That sounds like exactly what we want. How it works is it raises an assertion with the given message if the block returns false. Let's try it out:


Code :  ruby - fold - unfold
  1. assert_block "#{attribute} expected to be invalid when set to #{value}" do 
  2.   record.errors.invalid? attribute
  3. end 
Perfect, now we don't get that second error message.

If you notice, most assertion messages enclose the input variables in angled brackets <like this>. Let's do the same in our message and include the model name in there as  well so it's a little more descriptive:


Code :  ruby - fold - unfold
  1. assert_block "<#{model_class}.#{attribute}> expected to be invalid when set to <#{value}>" do 
  2.   record.errors.invalid? attribute
  3. end 
Finally, in our custom assertion we had two assertions, but the second one should catch anything the first one would have, so we can remove the first one. The end result looks like this:


Code :  ruby - fold - unfold
  1. def assert_invalid_value(model_class, attribute, value)
  2.   if value.kind_of? Array
  3.     value.each { |v| assert_invalid_value model_class, attribute, v }
  4.   else
  5.     record = model_class.new(attribute => value)
  6.     assert_block "<#{model_class}.#{attribute}> expected to be invalid when set to <#{value}>" do
  7.       record.valid? # Must be called to generate the errors
  8.       record.errors.invalid? attribute
  9.     end
  10.   end
  11. end 
And the error message now looks like this:


Code :   - fold - unfold
  1. <LineItem.quantity> expected to be invalid when set to <-1>
Much better.


In the previous article I had an idea for another custom assertion. Here it is:


Code :  ruby - fold - unfold
  1. assert_invalid_attributes LineItem, :quantity => [-1, 'foo', 2.5], :product => nil 
This is surprisingly easy to make if we use our assert_invalid_value method. We just have to loop through the given hash and call that method for each entry. Here's the code:


Code :  ruby - fold - unfold
  1. def assert_invalid_attributes(model_class, attributes)
  2.   attributes.each_pair do |attribute, value|
  3.     assert_invalid_value model_class, attribute, value
  4.   end
  5. end 
Oh Ruby, how do I love thee? Let me count the ways...

Last edited by ryanb (2006-09-28 16:48:41)


Railscasts - Free Ruby on Rails Screencasts

Offline

 

#2 2008-04-04 12:05:55

grosser
Ticketholder
Registered: 2008-04-04
Posts: 3

Re: Test Helper: Clean, Custom Assertion Messages

Enhancement: http://pragmatig.wordpress.com/2008/04/ … e-dry-way/

working with a set of valid attributes, so that things like:
username should not be the same as password, password should match password_confirmation ... can be tested

Offline

 
  • Index
  •  » Tutorials
  •  » Test Helper: Clean, Custom Assertion Messages

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson