Модульное тестирование приватных методов в Xcode
Я пробую тестовую разработку в игрушечном проекте. Я могу заставить тесты работать для открытого интерфейса с моими классами (хотя я все еще на грани, потому что я пишу больше тестирующего кода, чем в тестируемых методах).
Я склонен использовать много частных методов, потому что мне нравится поддерживать чистоту открытых интерфейсов; Тем не менее, я все еще хотел бы использовать тесты на этих методах.
Поскольку какао является динамическим языком, я все еще могу вызывать эти частные методы, но в моих тестах я получаю предупреждения о том, что мой класс может не отвечать на эти методы (хотя это явно так). Так как я люблю собирать без предупреждений, вот мои вопросы:
- Как отключить эти предупреждения в Xcode?
- Могу ли я сделать что-то еще, чтобы отключить эти предупреждения?
- Я делаю что-то не так, пытаясь проверить "белую коробку"?
7 ответов
Как отключить эти предупреждения в Xcode?
Не.
Могу ли я сделать что-то еще, чтобы отключить эти предупреждения?
Не.
Я делаю что-то не так, пытаясь проверить "белую коробку"?
Нет.
Решение состоит в том, чтобы переместить ваши частные методы в категорию в своем собственном заголовке. Импортируйте этот заголовок в файлы реализаций как реального класса, так и класса теста.
Помните, что в Objective-C на самом деле нет такой вещи, как "частные методы", и это не только потому, что это динамический язык. По своей конструкции Objective-C имеет модификаторы видимости для ivars, но не для методов - не случайно вы можете вызывать любой метод, который вам нравится.
Предложение @Peter великое. Чтобы дополнить его ответ, я использовал альтернативу (когда я не хочу / не нуждаюсь в заголовке только для частных методов), чтобы объявить категорию в самом файле модульного теста. (Я использую @interface MyClass (Test)
как имя.) Это отличный способ добавить методы, которые будут ненужными, в коде выпуска, например, для доступа к ivars, к которому имеет доступ тестируемый класс. (Это очевидно меньше проблемы, когда используются свойства.)
Я обнаружил, что такой подход облегчает выявление и проверку внутреннего состояния, а также добавление методов только для тестирования. Например, в этом файле модульного теста я написал -isValid
метод проверки правильности двоичной кучи. В производственном процессе этот метод был бы пустой тратой пространства, так как я предполагаю, что куча допустима - я забочусь об этом только при тестировании регрессий модульного теста, если я изменяю код.
Похоже, у другого вопроса есть ответ: есть ли способ подавления предупреждений в XCode?
Я имел дело с той же проблемой, когда начал работать с TDD несколько дней назад. Я нашел эту очень интересную точку зрения в книге по разработке под iOS для тестирования:
Меня часто спрашивали: "Должен ли я проверить свои личные методы?" Или связанный с этим вопрос "Как мне проверить свои личные методы?". Люди, задающие второй вопрос, предполагали, что ответ на первый вопрос - "Да", и теперь ищут для способа выставления частных интерфейсов их классов в их тестовых наборах.
Мой ответ основан на наблюдении тонкого факта: вы уже опробовали свои частные методы. Следуя подходу "красный – зеленый – рефакторинг", распространенному в разработке, управляемой тестами, вы создали открытые API-интерфейсы ваших объектов для выполнения работы, которую должны выполнять эти объекты. Благодаря этой работе, указанной в тестах, и продолжающемуся выполнению тестов, которые гарантируют вам, что вы ничего не сломали, вы можете организовать внутреннюю систему ваших классов по своему усмотрению.
Ваши частные методы уже протестированы, потому что все, что вы делаете, это рефакторинг поведения, для которого у вас уже есть тесты. Вы никогда не должны попадать в ситуацию, когда закрытый метод не проверен или не полностью протестирован, потому что вы создаете их только тогда, когда видите возможность очистить реализацию открытых методов. Это гарантирует, что частные методы существуют только для поддержки классов, которые они должны вызывать во время тестирования, потому что они определенно вызываются из открытых методов.
Если вы не хотите распределять свои реализации частных методов по нескольким исходным файлам, уточнение к решению "Категория" состоит в том, чтобы определить расширение (по существу, анонимную категорию - см . Документацию Apple) в файле заголовка, который импортируется обоими существующими классами. 'реализация и соответствующие исходные файлы модульного теста.
Использование Расширения позволяет компилятору предупреждать вас, если реализация основного метода отсутствует в основном блоке @implementation. Эта ссылка хорошо иллюстрирует это.
Хотя наличие частного заголовка или определение собственной категории, вероятно, являются более правильными решениями, есть и другое очень простое решение: приведите объект к (id) перед вызовом метода.
Легкая Работа. Шаги: 1. У вас есть -(NSString*)getTestString; в вашей целевой файл м для интерфейса Foo
Добавьте категорию в свой файл юнит-теста:
@interface DemoHomeViewController () -(NSString*)getTestString; @конец
Тогда делай что хочешь сейчас.