Recipe 7.20. Writing Custom Assertions


Problem

As your test suite grows, you find that you need assertions that are specific to your applications. You can, of course, create the tests you need with the standard assertions (it's just code), but you'd rather create custom assertions for tests that you use repeatedly. There's no need to repeat yourself in your tests.

Solution

Define a method in test_helper.rb. For example, you might find that you're writing many test methods that test whether a book's ISBN is valid. You want to create a custom assertion named assert_valid_isbn to perform this test. Add the method to ./test/test_helper.rb:

test/test_helper.rb:

ENV["RAILS_ENV"] = "test" require File.expand_path(File.dirname(__FILE__) + "/../config/environment") require 'test_help' class Test::Unit::TestCase   self.use_transactional_fixtures = true   self.use_instantiated_fixtures  = false    def assert_valid_isbn(isbn)     assert(/^\d{9}[\dxX]$/.match(isbn.to_s), "ISBN is invalid")   end end

You can now use your custom assertion in any of your tests.

test/unit/book_test.rb:

require File.dirname(__FILE__) + '/../test_helper' class BookTest < Test::Unit::TestCase   fixtures :books   def test_truth     assert_valid_isbn(1111111)    end end

Discussion

assert_valid_isbn is a wrapper around the assert method. The method body asserts that the argument passed in matches the Regexp object defined between by the contents of "//". If the match method of Regexp returns a MatchData object, the assertion succeeds. Otherwise it fails, and the second argument of assert is displayed as the error message.

The solution demonstrates the utility of defining custom assertions that might otherwise become a maintenance problem. For example, in January 2007, the current 10-digit ISBN will officially be replaced by a 13-digit identifier. You'll eventually need to modify your application to take this into account, and you'll need to test the new application. That modification will be a lot easier if you've centralized "knowledge" of the ISBN's format in one place, so you only have to change it once.

Even if you don't anticipate the code in your assertions to change, custom assertions can avoid code duplication. If you've got an assertion that contains complex logic, use assert_block method of the Test::Unit::Assertions module to test whether a block of code yields TRue or not. assert_block takes an error message as an argument and is passed a block of code to be tested. The format for assert_block is:

assert_block(message="assert_block failed.") {|| ...}   

See Also

  • RDoc on Test::Unit Assertions, http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit/Assertions.html




Rails Cookbook
Rails Cookbook (Cookbooks (OReilly))
ISBN: 0596527314
EAN: 2147483647
Year: 2007
Pages: 250
Authors: Rob Orsini

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net