Python Mock Raise Exception
-
Throw an Exception When Using the Unit-Testing Library
unittest
in Python - Manually Raise an Exception From a Function

The main aim of this article is to demonstrate how to throw an exception when using the unit testing library unittest
.
Throw an Exception When Using the Unit-Testing Library unittest
in Python
To verify that our code is stable and accounts for most of the use cases in the project’s scope, we must test it by giving it varied inputs. One of the libraries present in Python, unittest
, offers such functionality, allowing one to write and carry out different test cases.
While testing, it is necessary to be able to handle cases where the input is unexpected. We can handle such cases by throwing an exception detailing what is wrong with the given input.
Consider the following code:
class A:
def __init__(self):
pass
def computeData(self):
return 0
class B:
def method_to_test():
obj = A()
try:
print(obj.computeData())
except Exception as e:
print("Exception at method_to_test: " + str(e))
Let’s say that the function we want to test is method_to_test
. It initializes the object of another class A
and then calls one of its methods named computeData
in a try-except
block to catch any exceptions.
If we want to test the behavior of computeData
when a specific exception is thrown, we have to do so using the unittest
module.
Raise Exception Once
Considering the scenario mentioned above, it can also be the case that we want to have more control over when to throw an exception.
There can be plenty of reasons why such a need can arise. Depending on the implementation of your code, having more control over the behavior can be pretty helpful.
Assert Exception
While writing test cases, you may want to check whether your exceptions trigger or not. This is especially useful when you want to know if an exception was thrown or not.
This can help you spot earlier in your test cases if something goes wrong.
Mock Third-Party Modules
Third-party modules, depending on our implementation, can range from almost none to a lot. To test whether a third-party module behaves as intended, we must also test its behavior with varied outputs.
One such example would be request
, a widely used module when communicating over a network or sending/receiving data using HTTP.
Manually Raise an Exception From a Function
To manually throw an exception from the computeData
function, we have to use the side_effect
attribute.
Consider the following code:
import unittest
from unittest.mock import patch
from unittest.mock import MagicMock
class A:
def __init__(self) -> None:
pass
def computeData(self):
return 0
class B:
def method_to_test():
obj = A()
try:
print(obj.computeData())
except Exception as e:
print("Exception at method_to_test: " + str(e))
class Test(unittest.TestCase):
@patch.object(A, "computeData", MagicMock(side_effect=Exception("Test")))
def test_method(self):
B.method_to_test()
if __name__ == "__main__":
Test().test_method()
Output:
Exception at method_to_test: Test
In the solution, a new method, test_method
, is created to test the method method_to_test
. It is also important to note that the function is decorated with patch.object
.
The patch
decorator is provided in the module for patching modules and class-level attributes. To be more specific on what to patch, we use the patch.object
instead of patch
to patch the method directly.
In the decorator, the class name A
is passed. This indicates the object to be patched is a part of A
with the member name computeData
being passed.
The last parameter is a MagicMock
object, a subclass of Mock
, where we associate our required behavior to computeData
using the side_effect
attribute, which is to throw an exception in our case.
The general flow of the program is as follows:
- The
test_method
is called. - The
computeData
of classA
is patched. Aside_effect
is assigned, which in our case, is an exception. - The
method_to_test
of classB
is called. - The constructor of class
A
is called, with the instance stored inobj
. - The
computeData
is called. Due to the method being patched, an exception is thrown.
Raise an Exception Once
To only raise the exception once or have more control over the function’s behavior, side_effect
supports more than just a function call.
Currently, side_effect
supports:
Iterable
Callable
Exception
(Instance or Class)
Using Iterable
, we can make the method only raise an exception once.
class Test(unittest.TestCase):
@patch.object(A, "computeData", MagicMock(side_effect=[1, Exception("Test"), 3]))
def test_method(self):
B.method_to_test()
if __name__ == "__main__":
testClass = Test()
testClass.test_method()
testClass.test_method()
testClass.test_method()
Output:
1
Exception at method_to_test: Test
3
Due to the passed Iterable
, elements of our choice are patched, and we gain control over when to raise exceptions. Hence, the exception is only thrown the second time the function is called, and 1
and 3
are returned in other cases.
Assert Exception
To determine if a specific exception occurred or not, we can use unittest.TestCase.assertRaises
in case our desired exception is not thrown.
class Test(unittest.TestCase):
@patch.object(A, "computeData", MagicMock(side_effect=Exception("Test")))
def test_method(self):
self.assertRaises(KeyError, A.computeData)
if __name__ == "__main__":
Test().test_method()
Output:
Exception at method_to_test: Test
Traceback (most recent call last):
File "d:\Python Articles\a.py", line 28, in <module>
Test().test_method()
File "C:\Program Files\Python310\lib\unittest\mock.py", line 1369, in patched
return func(*newargs, **newkeywargs)
File "d:\Python Articles\a.py", line 25, in test_method
self.assertRaises(KeyError, A.computeData)
File "C:\Program Files\Python310\lib\unittest\case.py", line 738, in assertRaises
return context.handle('assertRaises', args, kwargs)
File "C:\Program Files\Python310\lib\unittest\case.py", line 201, in handle
callable_obj(*args, **kwargs)
File "C:\Program Files\Python310\lib\unittest\mock.py", line 1104, in __call__
return self._mock_call(*args, **kwargs)
File "C:\Program Files\Python310\lib\unittest\mock.py", line 1108, in _mock_call
return self._execute_mock_call(*args, **kwargs)
File "C:\Program Files\Python310\lib\unittest\mock.py", line 1163, in _execute_mock_call
raise effect
File "d:\Python Articles\a.py", line 17, in method_to_test
Exception: Test
We are making minor changes to our test_method
method, calling assertRaises
with two parameters, which resulted in the above output.
The two parameters can be defined as:
KeyError
- Any Exception you want to trigger is passed here.A.computeData
- The method which is supposed to throw the exception.
Mock Third-Party Modules
To mock a post
, like before, you must use the patch
decorator. A simple example can be as follows:
class Test(unittest.TestCase):
@patch(
"requests.post", MagicMock(side_effect=requests.exceptions.ConnectionError())
)
def test_method(self):
requests.post()
Output:
Traceback (most recent call last):
File "d:\Python Articles\a.py", line 33, in <module>
Test().test_method()
File "C:\Program Files\Python310\lib\unittest\mock.py", line 1369, in patched
return func(*newargs, **newkeywargs)
File "d:\Python Articles\a.py", line 30, in test_method
requests.post()
File "C:\Program Files\Python310\lib\unittest\mock.py", line 1104, in __call__
return self._mock_call(*args, **kwargs)
File "C:\Program Files\Python310\lib\unittest\mock.py", line 1108, in _mock_call
return self._execute_mock_call(*args, **kwargs)
File "C:\Program Files\Python310\lib\unittest\mock.py", line 1163, in _execute_mock_call
raise effect
requests.exceptions.ConnectionError
The functions from third-party modules can also be patched using the patch
decorator, allowing better debugging and more control over the scale of reliability of the product/program.
Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.
LinkedInRelated Article - Python Exception
- Open File Exception Handling in Python
- Rethrow Exception in Python
- Raise Exception in Python
- Handle NameError Exception in Python
- Python except Exception as e