Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Роль заглушки (Stub) в тестировании
Заглушка (Stub) — это ключевой концепт в изоляционном (модульном) тестировании, представляющий собой упрощённую, контролируемую замену реальной зависимости тестируемого модуля. Её основное предназначение — изоляция кода, который мы тестируем (SUT — System Under Test), от внешних или ещё не реализованных компонентов, чтобы сосредоточиться исключительно на его логике.
Основные цели использования заглушек
- Изоляция тестируемого кода. Заглушка заменяет реальные, сложные зависимости (базы данных, веб-сервисы, файловые системы, сторонние API), которые могут быть медленными, нестабильными или требующими специальных условий для работы. Это позволяет тестам выполняться быстро и детерминировано.
- Контроль входных данных и состояний. Заглушка программируется на возврат строго определённых, предсказуемых данных (как валидных, так и ошибочных) в ответ на вызовы тестируемого кода. Это позволяет проверить, как SUT ведёт себя в различных сценариях.
- Верификация косвенных выходов. Хотя основная задача заглушки — предоставление данных, некоторые её виды (например, Spy) могут также фиксировать факт и детали вызова (сколько раз вызван, с какими параметрами), что используется для проверки взаимодействия между модулями.
- Тестирование до реализации. В методологиях, подобных TDD (Test-Driven Development), заглушки позволяют писать и запускать тесты для модуля, даже когда его зависимости ещё не разработаны. Мы определяем ожидаемый интерфейс (контракт) и создаём его простую реализацию-заглушку.
Отличие от других тестовых двойников (Test Doubles)
Важно не путать заглушку с другими видами тестовых двойников:
- Mock: Объект, который ожидает определённых вызовов. Он используется для проверки поведения (behavior verification) — убедиться, что SUT корректно взаимодействует с зависимостью. Mock фокусируется на входе для зависимости.
- Stub: Объект, который возвращает заранее подготовленные данные. Он используется для подмены состояния (state verification) — обеспечить SUT нужными данными. Stub фокусируется на выходе из зависимости.
- Fake: Упрощённая, но рабочая реализация зависимости (например, база данных в памяти). Она не является ни заглушкой, ни mock'ом в чистом виде, а представляет собой функциональный, но непригодный для продакшена компонент.
Практический пример
Представим сервис PaymentProcessor, который зависит от внешнего PaymentGateway.
# Реальный класс, который мы НЕ хотим использовать в тестах
class RealPaymentGateway:
def charge(self, amount, token):
# Реальный HTTP-вызов к платёжному провайдеру
response = requests.post('https://api.payment.com/charge', ...)
return response.json()
# Тестируемый сервис
class PaymentProcessor:
def __init__(self, gateway):
self.gateway = gateway
def process_order(self, order):
# Некоторая бизнес-логика...
result = self.gateway.charge(order.amount, order.token)
if result['status'] == 'success':
order.mark_as_paid()
return True
return False
Для юнит-теста PaymentProcessor мы создадим заглушку:
# Заглушка для PaymentGateway
class StubPaymentGateway:
def __init__(self, fixed_response):
self.fixed_response = fixed_response
def charge(self, amount, token):
# Игнорируем параметры, всегда возвращаем заранее заданный ответ
return self.fixed_response
# Сам тест
def test_process_order_success():
# 1. ARRANGE: Подготовка заглушки и тестовых данных
success_response = {"status": "success", "transaction_id": "123"}
stub_gateway = StubPaymentGateway(success_response)
processor = PaymentProcessor(stub_gateway)
test_order = Order(amount=100, token="tok_abc")
# 2. ACT: Вызов тестируемого метода
result = processor.process_order(test_order)
# 3. ASSERT: Проверка бизнес-логики PaymentProcessor
assert result is True
assert test_order.is_paid is True
def test_process_order_failure():
# Заглушка возвращает ответ об ошибке
fail_response = {"status": "declined"}
stub_gateway = StubPaymentGateway(fail_response)
processor = PaymentProcessor(stub_gateway)
test_order = Order(amount=100, token="tok_abc")
result = processor.process_order(test_order)
assert result is False
assert test_order.is_paid is False
Вывод
Таким образом, заглушка — это фундаментальный инструмент для создания быстрых, стабильных и детерминированных модульных тестов. Она позволяет тестировать код в полной изоляции, имитируя различные сценарии поведения зависимостей (успех, ошибка, исключения) без необходимости развёртывания реальных внешних систем. Это напрямую способствует повышению качества кода, облегчает отладку и ускоряет процесс разработки.