import unittest.mock
# Создание обычного мок-объекта
mock_obj = unittest.mock.Mock()
# Создание MagicMock объекта (более мощный, имитирует магические методы)
magic_mock_obj = unittest.mock.MagicMock()
Затем можно настроить возвращаемые значения и поведение мок-объекта, например:
mock_obj.return_value = "Привет, мир!"
mock_obj.side_effect = Exception("Что-то пошло не так!")
Для создания мок-объекта с использованием библиотеки unittest.mock
можно использовать несколько классов и функций. Вот основные способы:
unittest.mock.Mock
:Mock
- это наиболее общий и гибкий способ создания мок-объектов. Он позволяет мокировать любой объект, функцию или класс.
import unittest.mock
# Создание базового мок-объекта
mock_object = unittest.mock.Mock()
# Настройка возвращаемого значения для метода
mock_object.some_method.return_value = "Результат замоканного метода"
# Настройка исключения, которое будет вызвано при вызове метода
mock_object.some_other_method.side_effect = ValueError("Произошла ошибка!")
# Проверка, был ли вызван метод и с какими аргументами
mock_object.some_method("arg1", "arg2")
mock_object.some_method.assert_called_with("arg1", "arg2")
# Проверка, был ли метод вызван хоть раз
mock_object.some_method.assert_called()
unittest.mock.MagicMock
:MagicMock
- это подкласс Mock
, который предоставляет дополнительные "магические методы" (методы, начинающиеся и заканчивающиеся на двойное подчеркивание, например, __str__
, __len__
и т.д.). Это позволяет более реалистично мокировать объекты, особенно те, которые используют эти методы.
import unittest.mock
mock_magic_object = unittest.mock.MagicMock()
# Мокирование магического метода __len__
mock_magic_object.__len__.return_value = 10
# Мокирование оператора сложения
mock_magic_object.__add__.return_value = "Result of addition"
unittest.mock.patch
:patch
- это декоратор или контекстный менеджер, который позволяет временно заменить объект в модуле на мок-объект. Это очень удобно для тестирования зависимостей.
import unittest
import unittest.mock
import my_module # Предположим, что у нас есть модуль my_module с функцией, которую нужно протестировать
def some_function_that_uses_my_module():
return my_module.some_function()
class MyTestCase(unittest.TestCase):
@unittest.mock.patch('my_module.some_function')
def test_some_function(self, mock_some_function):
# Настройка мок-объекта
mock_some_function.return_value = "Мокированный результат"
# Вызов функции, которая использует замоканный объект
result = some_function_that_uses_my_module()
# Проверка результата
self.assertEqual(result, "Мокированный результат")
# Проверка, что mock был вызван
mock_some_function.assert_called_once()
# Использование patch как контекстного менеджера:
def test_some_function_context_manager(self):
with unittest.mock.patch('my_module.some_function') as mock_some_function:
mock_some_function.return_value = "Мокированный результат из контекста"
result = some_function_that_uses_my_module()
self.assertEqual(result, "Мокированный результат из контекста")
mock_some_function.assert_called_once()
Важно: Выбор конкретного способа зависит от ситуации. Mock
и MagicMock
хороши для создания изолированных мок-объектов, а patch
удобен для тестирования интеграции, когда нужно заменить реальные зависимости на моки.