danidee danidee - 2 months ago 24
Python Question

assertRaises in unittest not catching Exception properly

I have a file testtest.py that i contains the code

import unittest

def add(self, a, b):
return a + b

class Test(unittest.TestCase):

def test_additon(self):
self.assertRaises(TypeError, add, 1 + '1', msg="Additon failed")
#self.assertRaises(TypeError, lambda: add(1 + '1'), msg="Addition failed")

if __name__ == '__main__':
unittest.main()


The problem is that
assertRaises
doesn't catch the exception properly and all my tests keep failing as errors not based on the condition, this is the output that I'm getting:

E
======================================================================
ERROR: test_additon (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "testtest.py", line 9, in test_additon
self.assertRaises(TypeError, add, 1 + '1', msg="Additon failed")
TypeError: unsupported operand type(s) for +: 'int' and 'str'

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (errors=1)


I know i can get around it by using lambda (i commented it out in the code) to make my tests properly catch the exceptions, but according to the docs, passing a callable and the arguments to
assertRaises
should work, as it will call the function internally by itself and be able to trap any exception that was raised.

assertRaises(*callable*, *args*, *kwargs*)


but it doesn't

if i run it with lambda which is a callable that would be evaluated later by
assertRaises
, it works as expected and i get this

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK


I'm running python 3.5


Python 3.5.2 (default, Jun 28 2016, 08:46:01)
[GCC 6.1.1 20160602] on linux


but i also get the same behaviour with
python2.7

Answer

You should be passing arguments to the callable separately, as separate arguments:

self.assertRaises(TypeError, add, 1, '1', msg="Additon failed")