views:

301

answers:

2

Hi all,

I am testing for Exceptions using unittest, for example:

self.assertRaises(UnrecognizedAirportError, func, arg1, arg2)

and my code raises:

raise UnrecognizedAirportError('From')

Which works well.

How do I test that the argument in the exception is what I expect it to be?

I wish to somehow assert that capturedException.argument == 'From'.

I hope this is clear enough - thanks in advance!

Tal.

+6  A: 

Like this.

>>> try:
...     raise UnrecognizedAirportError("func","arg1","arg2")
... except UnrecognizedAirportError, e:
...     print e.args
...
('func', 'arg1', 'arg2')
>>>

Your arguments are in args, if you simply subclass Exception.

See http://docs.python.org/library/exceptions.html#module-exceptions

If the exception class is derived from the standard root class BaseException, the associated value is present as the exception instance’s args attribute.


Edit Bigger Example.

class TestSomeException( unittest.TestCase ):
    def testRaiseWithArgs( self ):
        try:
            ... Something that raises the exception ...
            self.fail( "Didn't raise the exception" )
        except UnrecognizedAirportError, e:
            self.assertEquals( "func", e.args[0] )
            self.assertEquals( "arg1", e.args[1] )
        except Exception, e:
            self.fail( "Raised the wrong exception" )
S.Lott
+1, much cleaner than mine :)
Aiden Bell
I know there was some talk on python-dev a while back of modifying assertRaises to return the caught exception (and it was mentioned that both twisted and bzr hacked unittest to do just that). Does anybody know of any frameworks that implement that by default. Link to the python-dev note: http://mail.python.org/pipermail/python-dev/2008-July/081293.html
Aaron Maenpaa
A: 

assertRaises is a bit simplistic, and doesn't let you test the details of the raised exception beyond it belonging to a specified class. For finer-grained testing of exceptions, you need to "roll your own" with a try/except/else block (you can do it once and for all in a def assertDetailedRaises method you add to your own generic subclass of unittest's test-case, then have your test cases all inherit your subclass instead of unittest's).

Alex Martelli