Patches: Browse | Submit New | Admin

[#8716] Add option to Test::Unit::Assertions#assert_raise to allow subclasses

Date:
2007-02-17 00:24
Priority:
3
Submitted By:
Edwin Fine (efine)
Assigned To:
Nobody (None)
Category:
Developer Tools/Libs
State:
Open
Summary:
Add option to Test::Unit::Assertions#assert_raise to allow subclasses

Detailed description
The current assert_raise method tests that a specific list of exceptions is raised. This is often overly restrictive,
because sometimes one has to allow for the raising of a base exception OR any exception derived from that
base exception. This patch adds that functionality by providing an optional last parameter to assert_raise. I did this
to preserve DRY and to try to stay backward-compatible. Older test suites should run unchanged. However, newer test
suites that include the optional parameter will not run correctly with older test-unit code. This would be a problem
even if I added a new method.

The last (optional) parameter must be a hash of hashes. The primary hash key must be the symbol :opts. The hash corresponding
to that key must contain the entry :allow_subclasses => true. Any other case will revert to the current, more restrictive
behavior. If the last parameter is the correct type (hash of hashes) and contains the correct key (:opts), it will be
removed from the argument list during assert_raise processing. This will somewhat future-proof the code so that additional
parameters could be added if necessary.

I patched the trunk version of assertions.rb, but could not get the trunk to compile, so I copied assertions.rb to my
1.85 installation and tested it there with existing unit tests. It seems to work fine.

Example:

def test_for_nil_ruleset
  opts = {:opts => { :allow_subclasses => true }}
  assert_raise Validators::RuleException, opts do
    validator = Validators::ParamValidation.new(nil)
  end
end

Here's the CHANGELOG entry, if you need one:

Here's the patch to the trunk version (revision 11764) of assertions.rb:

@@ -98,17 +98,39 @@
           modules.any? {|mod| actual_exception.is_a?(mod)}
       end

+      def _expected_exception_or_subclass?(actual_exception, exceptions, modules) # :nodoc:
+        exceptions.any? {|cls| actual_exception.class <= cls} or
+          modules.any? {|mod| actual_exception.is_a?(mod)}
+      end
+
       ##
       # Passes if the block raises one of the given exceptions.
+      # If last argument is a hash with key of :opts, and value
+      # another hash {<some_sym> => true}, options will be
+      # processed. Currently there's only one option
+      # :allow_subclasses, which will make this assertion pass if
+      # the block raises one of the given exceptions <b>or
+      # any of their subclasses</b>.
       #
-      # Example:
+      # Examples:
       #   assert_raise RuntimeError, LoadError do
       #     raise 'Boom!!!'
       #   end
+      #
+      #   opts = {:opts => {:allow_subclasses => true}}
+      #   assert_raise RuntimeError, LoadError, opts do
+      #     raise 'Boom!!!'
+      #   end

       public
       def assert_raise(*args)
         _wrap_assertion do
+          allow_subclasses = false
+          if Hash === (opts = args.last) and opts.has_key?(:opts)
+            args.pop
+            allow_subclasses = (Hash === opts[:opts] and opts[:opts][:allow_subclasses])
+          end
+
           if Module === args.last
             message = ""
           else
@@ -127,7 +149,13 @@
             false
           end
           full_message = build_message(message, "<?> exception expected but was\n?", expected,
actual_exception)
-          assert_block(full_message) {_expected_exception?(actual_exception, exceptions, modules)}
+          assert_block(full_message) do
+            if allow_subclasses
+              _expected_exception_or_subclass?(actual_exception, exceptions, modules)
+            else
+              _expected_exception?(actual_exception, exceptions, modules)
+            end
+          end
           actual_exception
         end
       end


Regards,
Edwin Fine

Add A Comment: Notepad

Please login


Followup

No Followups Have Been Posted

Attached Files:

Name Description Download
No Files Currently Attached

Changes:

Field Old Value Date By
assigned_tozenspider2009-02-18 03:29zenspider
assigned_tonone2007-06-13 06:27zenspider
category_idMisc / Other Standard Library2007-05-30 04:16zenspider
category_idMisc / Other Standard Library2007-05-30 04:16zenspider
category_idCrypto / Digest / Compression2007-05-30 03:50zenspider
artifact_group_idNone2007-05-30 03:41zenspider