Swift Academy · Урок

Тестирование моделей представления

Тестируйте логику представления изолированно.

Урок 4 из 413 шагов

«Тестирование моделей представления» — бесплатный урок Swift Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.

Зачем тестировать ViewModel

ViewModel содержит логику представления, поэтому это наиболее ценное для модульного тестирования звено. Поскольку оно не зависит от UIKit или SwiftUI, его можно быстро и детерминированно тестировать изолированно.

Спроектировано для тестирования

Хорошо спроектированный ViewModel получает зависимости через свой инициализатор. Благодаря этому тесты могут подставлять имитации.

final class WeatherViewModel: ObservableObject {
    @Published var temperatureText = ""
    private let service: WeatherService

    init(service: WeatherService) {
        self.service = service
    }
}

Внедрение зависимостей

Скройте конкретные зависимости за протоколом. ViewModel зависит от абстракции, поэтому тесты могут внедрить mock.

protocol WeatherService {
    func fetchTemperature() async throws -> Double
}

Создание mock-объекта

mock соответствует протоколу и возвращает заранее подготовленные данные. Он позволяет точно контролировать, что видит ViewModel.

final class MockWeatherService: WeatherService {
    var stubbedTemperature: Double = 20
    var didCallFetch = false

    func fetchTemperature() async throws -> Double {
        didCallFetch = true
        return stubbedTemperature
    }
}

Базовый модульный тест

После внедрения mock-объекта Вы проверяете, правильно ли ViewModel преобразует данные.

func testFormatsTemperature() async {
    let mock = MockWeatherService()
    mock.stubbedTemperature = 25
    let vm = WeatherViewModel(service: mock)

    await vm.load()

    XCTAssertEqual(vm.temperatureText, "25 C")
}

Тестирование переходов состояний

ViewModel часто предоставляет перечисление состояний. Протестируйте каждую ветвь, передавая входные данные, которые приводят к ней.

func testLoadingThenLoaded() async {
    let vm = FeedViewModel(service: MockFeedService())
    XCTAssertEqual(vm.state, .loading)

    await vm.load()

    XCTAssertEqual(vm.state, .loaded(["A", "B"]))
}

Тестирование сценариев ошибок

Заставьте mock выбросить ошибку, чтобы проверить, корректно ли ViewModel обрабатывает сбои и предоставляет состояние ошибки.

final class FailingService: WeatherService {
    func fetchTemperature() async throws -> Double {
        throw URLError(.notConnectedToInternet)
    }
}

func testShowsErrorOnFailure() async {
    let vm = WeatherViewModel(service: FailingService())
    await vm.load()
    XCTAssertEqual(vm.state, .error)
}

Проверка взаимодействий

Иногда важно проверить, что зависимость была вызвана, а не только проверить результат. Флаги-шпионы в mock-объекте позволяют проверять поведение.

func testFetchIsCalled() async {
    let mock = MockWeatherService()
    let vm = WeatherViewModel(service: mock)
    await vm.load()
    XCTAssertTrue(mock.didCallFetch)
}

Тестирование вывода @Published

Вы можете подписаться на свойство @Published с помощью Combine, чтобы собирать отправленные значения и проверять последовательность.

var received: [String] = []
let cancellable = vm.$temperatureText.sink { received.append($0) }

await vm.load()

XCTAssertEqual(received.last, "25 C")
cancellable.cancel()

Как сохранять быстроту тестов

Поскольку mock-объекты возвращают данные мгновенно и настоящая сеть не используется, тесты ViewModel выполняются за миллисекунды. Избегайте настоящих таймеров и URLSession — внедряйте имитации также для часов и планировщиков.

Рекомендации

Эффективные тесты ViewModel:

  • Внедряйте все зависимости через протоколы
  • Проверяйте одно поведение в каждом методе теста
  • Покрывайте сценарии успеха, пустого результата и ошибки
  • Проверяйте опубликованные результаты, которые считывало бы представление

Быстрая проверка

Проверьте свои знания о тестировании ViewModel.

Итоги

Вы научились изолированно тестировать ViewModel:

  • Внедрять зависимости за протоколами
  • Использовать mock-объекты для управления входными данными и отслеживания вызовов
  • Покрывать состояния успеха, ошибки и пустого результата
  • Проверять результаты @Published и переходы состояний

Возможность тестирования ViewModel — результат разделения ответственности в MVVM.

Можно начать бесплатно

Изучай Swift с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
122
Уроки
409

Часто задаваемые вопросы

Урок «Тестирование моделей представления» бесплатный?

Да — полный текст урока «Тестирование моделей представления» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.

Чему я научусь в уроке «Тестирование моделей представления»?

Тестируйте логику представления изолированно. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Swift Academy?

Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Тестирование моделей представления»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Swift Academy?

Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Шаблон MVVM
  2. Связывание моделей представления с представлениями
  3. Шаблон координатора
  4. Тестирование моделей представления
← Назад к Swift Academy