Unit Testing with Python (Part 5) – Something Exceptional

Sometimes a unit test needs to do more than validate the good or correct path, what about failure scenarios? Let’s consider a search function, it returns an object when it finds what’s being requested but throws an exception when it can’t, any calling method would need to handle that exception and then behave accordingly.  Here’s an example implementation;

def find_user(username):
if username == "user1":
return dict(name="user1", id_no="12345")
raise Exception
def does_user_exist(username):
return True
except Exception:
return False

If the user exists, in this case if the calling function asked for user1, find_user gives back a dict and does_user_exist would return true.

If the user does not exist, i.e. the calling function passed in anything else, find_user throws an exception which does_user_exist handles, it then returns false.

Now to the point of this post, we want to test does_user_exist but we want to cover the both of the scenarios above. How do we have our unit test force an exception to be thrown? Easy! We just give our mock a “side_effect”, here’s the relevant information from the docs.

>>> mock = Mock(side_effect=KeyError('foo'))
>>> mock()
Traceback (most recent call last):
KeyError: 'foo'

Here’s what it looks like in a test;


import exception_example
import unittest
import mock
class ExceptionExampleTest(unittest.TestCase):
def test_does_user_exist(self):
def test_does_user_exist_no_user(self):
with mock.patch("exception_example.find_user", autospec=True, side_effect=Exception):
if __name__ == '__main__':

Here’s the result of me running this test;



Nice and simple! “side_effect”, is very helpful as it can also be used for when you want to return different values per call.

>>> mock.side_effect = [5, 4, 3, 2, 1]
>>> mock(), mock(), mock()
(5, 4, 3)

Take a look here, for more information.

Thank you again for reading, in the next (and final) post of this series, we will be taking a look at the implications of writing good unit tests.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s