Ответ
Заглушка (Stub) — это тестовый дублёр (test double), который заменяет реальную зависимость в тестируемой системе, предоставляя предопределённые, фиксированные ответы на вызовы своих методов. Её основная цель — изолировать тестируемый код от внешних сервисов или сложной логики.
Отличие Stub от Mock:
| Аспект | Stub (Заглушка) | Mock (Макет) |
|---|---|---|
| Цель | Предоставить данные для теста. | Проверить взаимодействие (какие методы вызывались, с какими аргументами). |
| Проверка | Не проверяет, как её использовали. Проверяется состояние тестируемой системы. | Проверяет, что ожидаемые вызовы были совершены. |
| Фокус | Состояние (State). | Поведение (Behavior). |
Практический пример:
Допустим, мы тестируем сервис PriceCalculator, который зависит от IDiscountService.
// Интерфейс зависимости
public interface IDiscountService
{
decimal GetDiscount(string userId);
}
// Реальная реализация (не используется в тесте)
public class RealDiscountService : IDiscountService
{
public decimal GetDiscount(string userId)
{
// Сложная логика: запрос к БД, вызов внешнего API и т.д.
return FetchDiscountFromDatabase(userId);
}
}
// Stub для теста
public class FixedDiscountStub : IDiscountService
{
private readonly decimal _fixedDiscount;
public FixedDiscountStub(decimal discount) => _fixedDiscount = discount;
public decimal GetDiscount(string userId)
{
// Игнорируем userId, всегда возвращаем фиксированную скидку
return _fixedDiscount;
}
}
// Тест с использованием Stub
[Test]
public void CalculatePrice_WithDiscount_AppliesCorrectly()
{
// Arrange
var discountStub = new FixedDiscountStub(10.0m); // Заглушка всегда возвращает 10%
var calculator = new PriceCalculator(discountStub); // Внедряем заглушку
decimal basePrice = 100.0m;
// Act
decimal finalPrice = calculator.CalculateFinalPrice("user123", basePrice);
// Assert
// Проверяем РЕЗУЛЬТАТ работы тестируемого метода, а не то, как вызвали заглушку.
Assert.AreEqual(90.0m, finalPrice); // 100 - 10%
}
Когда использовать Stub?
- Когда зависимость возвращает данные, необходимые для выполнения теста (например, конфигурация, курс валют, данные пользователя).
- Когда нужно симулировать определённое состояние внешней системы (например, «сервис недоступен» — заглушка бросает исключение).
- Когда реальная зависимость медленная, недетерминированная или её сложно настроить для теста (БД, внешние API).
Главный принцип: Stub делает тест стабильным, быстрым и изолированным, подменяя мир вокруг тестируемого объекта контролируемыми условиями.