Ответ
В библиотеке unittest.mock объекты Mock и MagicMock записывают все обращения к ним. Для проверки этих обращений используются специальные методы-утверждения (assertions).
Настройка поведения мока
Перед проверкой вызовов мок обычно настраивают:
mock.return_value: Атрибут, который определяет значение, возвращаемое при вызове мока.mock.side_effect: Позволяет задать более сложное поведение: выбросить исключение, вернуть разные значения при последовательных вызовах или выполнить функцию.
Проверка вызовов (Assertions)
Основные методы для проверки взаимодействия с моком:
mock.assert_called(): Проверяет, что мок был вызван хотя бы один раз.mock.assert_called_once(): Проверяет, что мок был вызван ровно один раз.mock.assert_not_called(): Проверяет, что мок не вызывался ни разу.mock.assert_called_with(*args, **kwargs): Проверяет, что последний вызов мока был с указанными аргументами.mock.assert_called_once_with(*args, **kwargs): Объединяетassert_called_once()иassert_called_with().mock.assert_any_call(*args, **kwargs): Проверяет, был ли хотя бы один вызов с указанными аргументами среди всех вызовов.mock.call_count: Целочисленный атрибут, содержащий количество вызовов мока.
Практический пример:
Предположим, мы тестируем функцию, которая использует внешний API для отправки уведомлений.
# Код, который мы тестируем
def send_notification(api_client, user_id, message):
if len(message) > 0:
api_client.send(user_id, text=message)
# Тест для этого кода
from unittest.mock import Mock
import unittest
class TestNotification(unittest.TestCase):
def test_send_notification_with_message(self):
# 1. Arrange: Создаем мок для API клиента
mock_api = Mock()
# 2. Act: Вызываем нашу функцию с моком
send_notification(mock_api, 123, "Hello!")
# 3. Assert: Проверяем, что метод .send() был вызван один раз
# и с правильными аргументами.
mock_api.send.assert_called_once_with(123, text="Hello!")
def test_send_notification_with_empty_message(self):
# 1. Arrange
mock_api = Mock()
# 2. Act
send_notification(mock_api, 123, "")
# 3. Assert: Проверяем, что метод .send() не вызывался
mock_api.send.assert_not_called()
if __name__ == '__main__':
unittest.main(argv=['first-arg-is-ignored'], exit=False)