Как создать мок-объект с использованием библиотеки `unittest.mock`?

Для создания мок-объекта с использованием `unittest.mock` можно использовать класс `Mock` или `MagicMock`.

Пример:
  
  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 удобен для тестирования интеграции, когда нужно заменить реальные зависимости на моки.

0