Swift, модификаторы доступа и модульное тестирование

Я просто обновился до Xcode 6 beta 4, где компилятор Swift теперь поддерживает модификаторы доступа.

Это вызвало у меня проблему, поскольку мои модульные тесты теперь не скомпилируются (из-за того, что классы не являются общедоступными).

Простым решением является, конечно же, сделать все тестируемые классы общедоступными, но это похоже на взломы (мое личное предпочтение - писать модульные тесты даже в непубличных классах).

В .NET и Java вы обычно можете разрешить модульные тесты уровня сборки (или уровня пакета в Java/OSGi) доступ к тестируемой сборке из сборки unit test. Я не понимал, как сделать что-то подобное в Свифте. Должен ли я сделать все классы доступными для unit test?

Ответ 1

Это известная проблема и упоминается в примечаниях к выпуску Beta 4. Возможно, вам захочется отменить изменение дизайна, пока не будет предоставлена ​​дополнительная информация.

Мы знаем, что наш дизайн управления доступом не очень подходит для модульного тестирования (и это было в примечаниях к выпуску), мы оцениваем ситуацию, чтобы увидеть, что мы можем сделать.

- Крис Лэттнер

Ограничение системы контроля доступа заключается в том, что модульные тесты не могут взаимодействовать с классами и методами в приложении, если они не являются общедоступными. Это связано с тем, что цель unit test не является частью модуля приложения.

- Примечания к выпуску Xcode beta 4

https://github.com/ksm/SwiftInFlux#limitations-of-current-access-control-design

Ответ 2

С Swift 2 вам теперь разрешено тестировать свой класс, не помечая его как общедоступный. Вам просто нужно использовать ключевое слово @testable, и компилятор позаботится об отдыхе.

Слайд из Что нового в Xcode WWDC 2015:

Ответ 3

Вы можете просто добавить исходные файлы из своей цели в тестовый объект. Затем они будут частью вашей тестовой цели, и вы сможете получить к ним доступ.

Ответ 4

Я думаю, что у меня есть лучшее решение, чем сделать все публичным. Просто сделайте StoryBoard членом тестовой цели так же, как и все ваши ViewControllers. Затем создайте StoryBoard в своем тестовом классе, используя тестовый комплект, вместо того, чтобы использовать nil или основной комплект. Отметьте мой пост здесь для примера кода.

var storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle(forClass: self.dynamicType))
vc = storyboard.instantiateViewControllerWithIdentifier("LoginVC") as LoginViewController
vc.loadView()