Ответ 1
(Обратите внимание, что Swift 2 добавляет атрибут @testable
, который может использовать внутренние методы и свойства для тестирования. См. комментарии @JeremyP ниже для получения дополнительной информации.)
Нет. В Swift частный частный. Компилятор может использовать этот факт для оптимизации, поэтому в зависимости от того, как вы используете это свойство, законным для компилятора является его удаление, вложение в него или выполнение каких-либо других действий, которые могли бы дать правильное поведение на основе кода, файл. (Действительно ли оптимизатор на самом деле тот умный сегодня или нет, это разрешено.)
Теперь, конечно, если вы объявите свой класс @objc
, то вы можете разбить эти оптимизации, и вы можете пойти с ObjC, чтобы прочитать его. И есть причудливые обходные пути, которые могут позволить вам использовать Swift для вызова произвольных @objc
открытых методов (например, zero-timeout NSTimer
). Но не делайте этого.
Это классическая проблема с тестированием, и классический тестовый ответ не проверяет этот способ. Не проверяйте внутреннее состояние. Если буквально невозможно сказать извне, что что-то случилось, то нечего тестировать. Перепроектируйте объект таким образом, чтобы его можно было проверить в его общедоступном интерфейсе. И обычно это означает состав и издевательства.
Вероятно, наиболее распространенной версией этой проблемы является кэширование. Очень сложно проверить, что что-то на самом деле кэшировано, поскольку единственное различие может заключаться в том, что оно выполняется быстрее. Но это все еще проверяемо. Переместите функциональность кэширования в другой объект, и пусть ваш объект под тестом примет пользовательский объект кэширования. Затем вы можете передать макет, который записывает, были ли сделаны правильные запросы к кешу (или сетевые вызовы, или вызовы базы данных, или независимо от того, что имеет внутреннее состояние).
В основном ответ: редизайн, чтобы было легче протестировать.
ОК, но вы действительно, действительно, действительно нуждаетесь в этом... как это сделать? Хорошо, это возможно, не нарушая мир.
Создайте функцию внутри проверяемого файла, который предоставляет предмет, который вы хотите. Не метод. Просто бесплатная функция. Затем вы можете поместить эту вспомогательную функцию в #if TEST
и установить TEST
в своей тестовой конфигурации. В идеале я бы сделал функцию на самом деле проверять то, что вам нужно, а не подвергать переменную (и в этом случае, возможно, вы можете позволить функции быть внутренней или даже публичной). Но в любом случае.