Python – Getting Started with Python Mock

The following examples all use the Python Mock library. This post is intended as a quick “Getting Started” for someone who is new to using Python Mock. For more advanced usages you can refer to the Python Mock Documentation.

You can download the code from GitHub here. (Follow the instructions in the Readme)

Setup

You will need to install the mock library:

pip install -U mock

Here is the code we will use as our “code under test” to write these example tests. You can put this code in a file called my_module.py:

class MyClass():
    def my_method(self):
        pass
 
class SomeOtherClass():
    def method_under_test(self):
        myclass = MyClass()
        return myclass.my_method()

In our Tests we will be testing class SomeOtherClass and method method_under_test and mocking the class MyClass as well as mocking the method my_method.

Your test file will need the following import statements:

import unittest
from my_module import MyClass, SomeOtherClass
from mock import patch, Mock

Mock Examples

To mock a method in a class to return a specific value use @patch.object.

@patch.object(MyClass, 'my_method')
def test_shouldReturnValue_whenMethodIsMocked(self, mock_my_method):
    # Arrange
    mock_my_method.return_value = True
    some_other_class = SomeOtherClass()

    # Act
    result = some_other_class.method_under_test()

    # Assert
    self.assertTrue(result)

To mock an entire class to test interactions with that class use @patch.

@patch('my_module.MyClass')
def test_shouldRecordMethodWasCalled_whenClassIsMocked(self, mock_my_class):
    # Arrange
    some_other_class = SomeOtherClass()

    # Act
    some_other_class.method_under_test()

    # Assert
    self.assertTrue(mock_my_class.called)

To mock an entire class with @patch and still set the return value of a method in that class, grab the instance of the mock object’s return value and set the method’s return value on the instance. There is a section on the patch page explaining how to do this.

@patch('my_module.MyClass')
def test_shouldReturnValue_whenReturnValueIsSetOnMethodOfMockedClass(self, mock_my_class):
    # Arrange
    mc = mock_my_class.return_value
    mc.my_method.return_value = True
    some_other_class = SomeOtherClass()

    # Act
    result = some_other_class.method_under_test()

    # Assert
    self.assertTrue(result)

To mock a method in a class with @patch.object but return a different value each time it is called, use side_effect. Side effect allows you to define a custom method and have that method called each time your mock method is called. The value returned from this method will be used as the return value your mock method.

@patch.object(MyClass, 'my_method')
def test_shouldReturnANewValueEachTime_whenMethodIsMockedUsingSideEffect(self, mock_my_method):
	# Arrange
	list_of_return_values = [True, False, False]

	def side_effect():
		return list_of_return_values.pop()

	mock_my_method.side_effect = side_effect

	some_other_class = SomeOtherClass()

	# Act
	result_one = some_other_class.method_under_test()
	result_two = some_other_class.method_under_test()
	result_three = some_other_class.method_under_test()

	# Assert
	self.assertFalse(result_one)
	self.assertFalse(result_two)
	self.assertTrue(result_three)

Run The Tests

To run the tests, put the imports and tests into a file called tests.py in a class called SomeOtherClassTest.

You can then run the tests with the following command:

python -m unittest tests.SomeOtherClassTest

You will see the output:

Ran 4 tests in 0.005s

OK

Summary

There are many other features in the Python Mock library, but these are the basics that will help you get started!

I hope that helps!