Как протестировать приватные методы класса в Swift?

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

Ответ

Да, но не напрямую. Тестирование приватных методов нарушает инкапсуляцию и считается антипаттерном. Лучше тестировать через публичный интерфейс. Если необходимо, используйте обходные пути:

1. @testable import (для internal) Доступно только для модулей с включенным тестированием (Enable Testability = YES).

@testable import MyModule

func testInternalMethod() {
    let sut = MyClass()
    // Доступны только internal-члены, не private/fileprivate
}

2. Fileprivate-расширение в том же файле

// В исходном файле MyClass.swift
class MyClass {
    fileprivate func privateMethod() -> Int { return 42 }
}

// Расширение для тестов в том же файле
#if DEBUG
extension MyClass {
    func exposedForTesting() -> Int {
        return privateMethod()
    }
}
#endif

3. Рефлексия (не рекомендуется) Хрупкий подход, ломается при изменении сигнатур.

let mirror = Mirror(reflecting: object)
// Сложный и ненадежный доступ к приватным свойствам

Рекомендация: Проектируйте классы так, чтобы приватная логика вызывалась через публичные методы, которые легко тестировать. Если метод сложно протестировать — возможно, он должен быть вынесен в отдельный тестируемый компонент.