unittest: assertRaises() with an instance instead of a type
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Wed Mar 28 14:07:01 EDT 2012
On Wed, 28 Mar 2012 14:28:08 +0200, Ulrich Eckhardt wrote:
> Hi!
>
> I'm currently writing some tests for the error handling of some code. In
> this scenario, I must make sure that both the correct exception is
> raised and that the contained error code is correct:
>
>
> try:
> foo()
> self.fail('exception not raised')
> catch MyException as e:
> self.assertEqual(e.errorcode, SOME_FOO_ERROR)
> catch Exception:
> self.fail('unexpected exception raised')
First off, that is not Python code. "catch Exception" gives a syntax
error.
Secondly, that is not the right way to do this unit test. You are testing
two distinct things, so you should write it as two separate tests:
def testFooRaisesException(self):
# Test that foo() raises an exception.
self.assertRaises(MyException, foo)
If foo does *not* raise an exception, the unittest framework will handle
the failure for you. If it raises a different exception, the framework
will also handle that too.
Then write a second test to check the exception code:
def testFooExceptionCode(self):
# Test that foo()'s exception has the right error code.
try:
foo()
except MyException as err:
self.assertEquals(err.errorcode, SOME_FOO_ERROR)
Again, let the framework handle any unexpected cases.
If you have lots of functions to test, write a helper function:
def catch(exception, func, *args, **kwargs):
try:
func(*args, **kwargs)
except exception as err:
return err
raise RuntimeError('no error raised')
and then the test becomes:
def testFooExceptionCode(self):
# Test that foo()'s exception has the right error code.
self.assertEquals(
catch(MyException, foo).errorcode, SOME_FOO_ERROR
)
(By the way, I have to question the design of an exception with error
codes. That seems pretty poor design to me. Normally the exception *type*
acts as equivalent to an error code.)
--
Steven
More information about the Python-list
mailing list