← Назад ко всем вопросам

Как работает unittest.mock.patch и в каких случаях его используют?

1️⃣ Как кратко ответить

unittest.mock.patch — это инструмент в Python, который временно заменяет объекты в модуле на моки или другие объекты во время тестирования. Он используется для изоляции тестируемого кода от его зависимостей, позволяя тестировать код в контролируемой среде.

2️⃣ Подробное объяснение темы

unittest.mock.patch — это часть модуля unittest.mock, который входит в стандартную библиотеку Python и предназначен для создания и управления мока-объектами. Моки позволяют подменять реальные объекты в коде на их имитации, что полезно для тестирования.

Зачем это нужно?

При тестировании кода часто возникает необходимость изолировать тестируемый компонент от его зависимостей. Например, если ваш код взаимодействует с внешними API, базами данных или файловой системой, вы не хотите, чтобы тесты зависели от этих внешних ресурсов. patch позволяет временно заменить эти зависимости на моки, чтобы тесты были быстрыми, надежными и независимыми от внешних факторов.

Как это работает?

patch временно заменяет указанный объект на мока или другой объект на время выполнения теста. После завершения теста оригинальный объект восстанавливается. Это достигается с помощью контекстного менеджера или декоратора.

Пример использования

Представьте, что у вас есть функция, которая отправляет HTTP-запрос:

import requests
​
def fetch_data(url):
    response = requests.get(url)
    return response.json()

Чтобы протестировать эту функцию, вы не хотите делать реальный HTTP-запрос. Вместо этого вы можете использовать patch для замены requests.get на мока:

from unittest.mock import patch
import unittest
​
class TestFetchData(unittest.TestCase):
    @patch('requests.get')
    def test_fetch_data(self, mock_get):
        # Настраиваем мок-объект
        mock_get.return_value.json.return_value = {'key': 'value'}
        ​
        # Вызываем тестируемую функцию
        result = fetch_data('http://example.com')
        ​
        # Проверяем, что функция возвращает ожидаемый результат
        self.assertEqual(result, {'key': 'value'})
        ​
        # Проверяем, что requests.get был вызван с правильным URL
        mock_get.assert_called_once_with('http://example.com')
​
if __name__ == '__main__':
    unittest.main()

Как использовать patch?

  • Как декоратор: Используется для замены объекта на время выполнения функции. В примере выше @patch('requests.get') заменяет requests.get на мока.

  • Как контекстный менеджер: Используется для замены объекта в блоке кода. Это удобно, если вы хотите ограничить область действия мока:

    with patch('requests.get') as mock_get:
        mock_get.return_value.json.return_value = {'key': 'value'}
        result = fetch_data('http://example.com')
        assert result == {'key': 'value'}
    

Где применяется?

  • Изоляция тестов: Удаление зависимости от внешних систем, таких как базы данных или API.
  • Контроль над поведением: Задание предсказуемого поведения для тестируемых функций.
  • Проверка взаимодействий: Убедиться, что функции вызываются с ожидаемыми параметрами.

Тема: Тестирование
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки