pythonunit-testingtestingpython-unittest

Correct usage of assertRaises in Python unit tests


I'm trying to figure out how to correctly use assertRaises() of the Python unittest module. I have a ValueError in my function that gets raised. However, when testing in my unit tests, I'm getting mixed results with two different ways of using assertRaises().

When I write the test like this, it works:

import unittest

class MyTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        pass

    def test_error(self):
        with self.assertRaises(ValueError):
            func(a)

However, if I write my test like below, it does not work even though the ValueError gets raised:

    def test_error(self):
        self.assertRaises(ValueError, func(a))

Why would one way work and not the other?


Solution

  • The assertRaises method takes a variable argument list, where the first argument is the function object, and the optional other arguments are the function arguments. You have to call it either this way (the usual way):

    def test_error(self):
        self.assertRaises(ValueError, func, a)
    

    Or using a lambda:

    def test_error(self):
        self.assertRaises(ValueError, lambda: func(a))
    

    The problem with your call is that it would execute your function before calling assertRaises, as the result of the function call instead of the function itself is passed as an argument - so the exception would occur before assertRaises could handle it.

    Having said that, I would always prefer the context manager variant, as it is better readable.