How to properly use unit-testing's assertRaises() with NoneType objects?
If you are using python2.7 or above you can use the ability of assertRaises to be use as a context manager and do:
with self.assertRaises(TypeError):
self.testListNone[:1]
If you are using python2.6 another way beside the one given until now is to use unittest2 which is a back port of unittest new feature to python2.6, and you can make it work using the code above.
N.B: I'm a big fan of the new feature (SkipTest, test discovery ...) of unittest so I intend to use unittest2 as much as I can. I advise to do the same because there is a lot more than what unittest come with in python2.6 <.
The problem is the TypeError
gets raised 'before' assertRaises
gets called since the arguments to assertRaises
need to be evaluated before the method can be called. You need to pass a lambda
expression like:
self.assertRaises(TypeError, lambda: self.testListNone[:1])
The usual way to use assertRaises
is to call a function:
self.assertRaises(TypeError, test_function, args)
to test that the function call test_function(args) raises a TypeError.
The problem with self.testListNone[:1]
is that Python evaluates the expression immediately, before the assertRaises
method is called. The whole reason why test_function
and args
is passed as separate arguments to self.assertRaises
is to allow assertRaises
to call test_function(args)
from within a try...except
block, allowing assertRaises
to catch the exception.
Since you've defined self.testListNone = None
, and you need a function to call, you might use operator.itemgetter like this:
import operator
self.assertRaises(TypeError, operator.itemgetter, (self.testListNone,slice(None,1)))
since
operator.itemgetter(self.testListNone,slice(None,1))
is a long-winded way of saying self.testListNone[:1]
, but which separates the function (operator.itemgetter
) from the arguments.