19
Mocking using pytest
Pytest is a unit test module in python.
Mocking is a way of mimicking the working of a service in
a way to substitute for the real one.
In this post I'll be focussing on mocking different types of methods present in a class.
Class ABC has been defined in a python file python_class.py
class ABC:
def call(self):
self.static_method()
ABC.class_method()
self.instance_method()
self._ABC__private_instance_method()
ABC._ABC__private_class_method()
ABC._ABC__private_static_method()
@staticmethod
def static_method():
print("static_method")
@classmethod
def class_method(cls):
print("class_method")
def instance_method(self):
print("instance method")
def __private_instance_method(self):
print("private instance method")
@classmethod
def __private_class_method(cls):
print("private class method")
@staticmethod
def __private_static_method():
print("private static method")
Yeah I know this isn't how class methods and static methods should be used, but that's not on today's agenda.
In the call method, we can see that there are 6 other methods being called. That's where we need to mock the methods - the place where they're being called/being used instead of where they've been defined.
But before that we need to install 2 packages: pytest, pytest-mock
from unittest.mock import Mock
from python_class import ABC
class TestPythonClass():
def test_all_methods(self, mocker):
directory = "python_class.ABC"
instance_mock = mocker.patch(f"{directory}.instance_method", return_value=Mock())
static_mock = mocker.patch(f"{directory}.static_method", return_value=Mock())
class_method_mock = mocker.patch(f"{directory}.class_method", return_value=Mock())
pvt_instance_mock = mocker.patch(f"{directory}._ABC__private_instance_method", return_value=Mock())
pvt_class_mock = mocker.patch(f"{directory}._ABC__private_class_method", return_value=Mock())
pvt_static_mock = mocker.patch(f"{directory}._ABC__private_static_method", return_value=Mock())
ABC().call()
assert instance_mock.call_count == 1
assert static_mock.call_count == 1
assert class_method_mock.call_count == 1
assert pvt_instance_mock.call_count == 1
assert pvt_class_mock.call_count == 1
mocker is a fixture that is shipped with the pytest-mock module. We can simply pass it on as an argument during the test method definition without importing.
In this way I've mocked 6 different types of methods:
- instance method
- class method
- static method
- private instance method
- private class method
- private static method
Lemme know in case I missed something or I need to add anything.
19