Mocks and Python

In my post Unit testing in Python I covered the basics of writing unit tests within Python.

Testing also sometimes involves writing stubs and/or using mock objects.

As Python is a dynamic language which supports duck typing, we can fairly easily create stub objects, but a mocking framework can make things even simpler. However a good mock framework also gives us the ability to check whether a method was called and assert that it was not called, or was called the correct number of times.

Using MagicMock

MagicMock is a class within the unittest.mock module used to patch methods. Patching being the process of swapping out methods with our mock methods.

Here’s a Calculator class with an add method

class Calculator:
    def add(self, a, b):
        return a + b

Let’s assume we want to mock/patch the add method and ensure it’s called a certain number of times

Note: this is a contrived example as we are explicitly calling the add method, thus know how many times it’s called, but it’s a simple enough example to see how things fit together.

from unittest.mock import MagicMock 

class CalculatorTests(TestCase):

    @classmethod
    def setUpClass(cls):
        cls.c = Calculator()

    def test_add(self):
        self.c.add = MagicMock(name='add')
        self.c.add.return_value = 5

        self.assertEqual(5, self.c.add(3, 2))
        self.c.add.assert_called_once_with(3, 2)

In the above we’re using assertEqual just to demonstrate the use of the return_value. The call to the add method within the assertEqual demonstrates how we still call our patched method in the same way and then finally we use assert_called_once_with(3, 2) to assert that the add method was call once and with the expected parameters.

References

unittest.mock — mock object library