[Tutor] Proper way to unit test the raising of exceptions?

Peter Otten __peter__ at web.de
Sun Apr 1 11:11:00 EDT 2018


Simon Connah via Tutor wrote:

> Hi,
> I'm just wondering what the accepted way to handle unit testing exceptions
> is? I know you are meant to use assertRaises, but my code seems a little
> off. 

> try:
>     some_func()
> except SomeException:   
>     self.assertRaises(SomeException) 

The logic is wrong here as you surmise below. If you catch the exception 
explicitly you have to write

try:
    some_func()
except SomeException:
    pass  # OK
else:
    self.fail("no exception raised")

Alternatively you can write

self.assertRaises(SomeException, some_func)

which is already better, but becomes a bit hard to read once some_func takes 
arguments:

self.assertRaises(SomeException, some_func, "one", two=42)

Therefore I recommend using assertRaises() as a context manager:

with self.assertRaises(SomeException):
    some_func("one", two=42)

This has the advantage that some_func() appears with its args as it would in 
normal code, and that you can also test expressions:

with self.assertRaises(ZeroDivisionError):
   MyNumber(1)/0

>     Is there a better way to do this at all?
> The problem with the above code is that if no exception is raised the code
> completely skips the except block and that would mean that the unit test
> would pass so, I considered adding: self.fail('No exception raised') at
> the end outside of the except block but not sure if that is what I need to
> do. Any help is appreciated.





More information about the Tutor mailing list