В чем разница между моками и стабами в тестировании?

«В чем разница между моками и стабами в тестировании?» — вопрос из категории Тестирование, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Моки и стабы — это виды тестовых заглушек (test doubles), но с разными целями.

Стаб (Stub)

  • Цель: Предоставить тестируемому коду предопределённые данные, заменяя реальную зависимость.
  • Не проверяет взаимодействие, только возвращает фиктивные данные.
  • Используется для изоляции тестируемого модуля.

Пример стаба на Swift:

protocol DataService {
    func fetchUser() -> String
}

class StubDataService: DataService {
    func fetchUser() -> String {
        return "Test User" // Жёстко заданное значение
    }
}

Мок (Mock)

  • Цель: Проверить взаимодействие (какие методы были вызваны, с какими параметрами).
  • Записывает вызовы и позволяет делать утверждения (assertions) о них.
  • Используется для проверки поведения (behavior verification).

Пример мока на Swift:

class MockDataService: DataService {
    var fetchUserCallCount = 0

    func fetchUser() -> String {
        fetchUserCallCount += 1 // Фиксация факта вызова
        return ""
    }
}

// В тесте:
// let mock = MockDataService()
// ... выполнение теста ...
// XCTAssertEqual(mock.fetchUserCallCount, 1)

Ключевое отличие:

  • Стаб — для подмены данных (state).
  • Мок — для проверки вызовов (behavior).