Ответ
Да, но не напрямую. Тестирование приватных методов нарушает инкапсуляцию и считается антипаттерном. Лучше тестировать через публичный интерфейс. Если необходимо, используйте обходные пути:
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)
// Сложный и ненадежный доступ к приватным свойствам
Рекомендация: Проектируйте классы так, чтобы приватная логика вызывалась через публичные методы, которые легко тестировать. Если метод сложно протестировать — возможно, он должен быть вынесен в отдельный тестируемый компонент.
Ответ 18+ 🔞
А, ну это классика, блядь! Опять эти приватные методы, как заноза в жопе. Слушай, давай по-честному: тестировать их напрямую — это пиздец какой антипаттерн, ёпта. Это как пытаться проверить, что у человека в желудке, через жопу — технически можно, но неебически неудобно и против всех правил приличия. Ты же инкапсуляцию ломаешь нахуй!
Но если прям приперло, как говно к стенке, и по-другому никак, есть несколько кривых тропинок. Только смотри, не обосрись на них.
Первый способ, самый цивилизованный — @testable import.
Это как если бы ты был родственником, которому разрешили зайти в квартиру, но в спальню — ни ногой. Работает только для internal методов, private ему всё равно как слону дробина.
@testable import MyModule // Включи в настройках таргета Enable Testability, а то нихуя не выйдет
func testInternalMethod() {
let sut = MyClass()
// Тут тебе доступно всё internal-наследие, но приватное — хуй тебе, а не доступ.
}
Второй способ — хитрость для fileprivate.
Ты в том же файле, где твой класс, делаешь расширение специально для тестов. Как потайная дверь для своих.
// Это в MyClass.swift, блядь
class MyClass {
fileprivate func secretSauce() -> Int { return 666 }
}
// А это — наш чит-код, только для DEBUG
#if DEBUG
extension MyClass {
func exposeTheSauceForTesting() -> Int {
return secretSauce() // Вот и добрались, сука!
}
}
#endif
Третий способ — рефлексия, она же зеркало.
Это уже полный пиздец и шаманство, ядрёна вошь. Сломается от чиха, если сигнатуру метода поменяют. Бери на вооружение, только если готов каждый день переписывать тесты.
let mirror = Mirror(reflecting: object)
// Дальше начинается ад: ковыряешься в children, ищешь нужное свойство...
// Один хрен, private-метод так не выцепишь. Хуйня, короче.
А теперь, блядь, главное, что я хочу донести, чтобы у тебя в башке щёлкнуло. Правильный путь — это спроектировать классы так, чтобы не было этой боли в сраке. Если приватный метод настолько сложный, что его хочется отдельно потестировать — вынеси его, сука, в отдельную сущность! Сделай из него public протокол с реализацией, и тестируй её в открытую. Или убедись, что он вызывается через публичные методы, которые ты и будешь проверять.
Запомни, как отче наш: если тебе приходится выёбываться, чтобы протестировать кусок кода — это первый звонок, что архитектура говно. Не усложняй, переосмысли.