модульное тестирование приватных методов в xcode

<p>я испытываю тестовую разработку в игрушечном проекте. я могу заставить тесты работать для открытого интерфейса с моими классами (хотя я все еще на грани, потому что я пишу больше тестирующего кода, чем в тестируемых методах).</p><p>я склонен использовать много частных методов, потому что мне нравится поддерживать чистоту открытых интерфейсов; тем не менее, я все еще хотел бы использовать тесты на этих методах.</p><p>поскольку какао является динамическим языком, я все еще могу вызывать эти закрытые методы, но в своих тестах я получаю предупреждения о том, что мой класс может не отвечать на эти методы (хотя это явно так). так как я люблю собирать без предупреждений, вот мои вопросы:</p><ol> <li>как отключить эти предупреждения в xcode?</li> <li>могу ли я сделать что-то еще, чтобы отключить эти предупреждения?</li> <li>я делаю что-то не так, пытаясь проверить "белую коробку"?</li> </ol>

<blockquote> <p>как отключить эти предупреждения в xcode?</p> </blockquote><p>не.</p><blockquote> <p>могу ли я сделать что-то еще, чтобы отключить эти предупреждения?</p> </blockquote><p>не.</p><blockquote> <p>я делаю что-то не так, пытаясь проверить "белую коробку"?</p> </blockquote><p>нет.</p><p>решение состоит в том, чтобы переместить ваши частные методы в категорию в своем собственном заголовке. импортируйте этот заголовок в файлы реализаций как реального класса, так и класса теста.</p>

<p>помните, что на самом деле в objective-c нет такой вещи, как "частные методы", и это не только потому, что это динамический язык. по своей конструкции objective-c имеет модификаторы видимости для ivars, но не для методов - не случайно вы можете вызывать любой метод, который вам нравится.</p><p><strong> @ питер </strong> - отличное предложение. чтобы дополнить его ответ, я использовал альтернативу (когда я не хочу/не нужен заголовок только для частных методов), чтобы <strong> объявить категорию в самом файле модульного теста </strong>. (я использую <code>@interface myclass (test)</code> в качестве имени.) это отличный способ добавить методы, которые были бы ненужными, в коде выпуска, например, для доступа к ivars, к которому имеет доступ тестируемый класс. (это очевидно меньше проблем, когда используются свойства.)</p><p>я обнаружил, что такой подход облегчает выявление и проверку внутреннего состояния, а также добавление методов только для тестирования. например, в <a href="https://github.com/davedelong/chdatastructures/blob/master/test/chheaptest.m">этот файл модульного теста</a> я написал метод <code>-isvalid</code> для проверки правильности двоичной кучи. в производственном процессе этот метод был бы пустой тратой пространства, так как я предполагаю, что куча допустима - я забочусь об этом только при тестировании регрессий модульного теста, если я изменяю код.</p>

<p>похоже, что другой вопрос имеет ответ: <a href="https://stackoverflow.com/questions/194666/is-there-a-way-to-suppress-warnings-in-xcode">есть ли способ подавления предупреждений в xcode?</a> </p>

<p>хотя наличие частного заголовка или определение собственной категории, вероятно, являются более правильными решениями, есть и другое очень простое решение: приведите объект к (id) перед вызовом метода.</p>

<p>я имел дело с той же проблемой, когда начал работать с tdd несколько дней назад. я нашел эту очень интересную точку зрения в <a href="https://rads.stackoverflow.com/amzn/click/com/0321774183">test-driven ios development</a> книге:</p><blockquote> <p>меня часто спрашивали: "должен ли я проверить свои личные методы?" или связанный с этим вопрос "как мне проверить свои личные методы?". люди, задающие второй вопрос, предполагали, что ответ на первый - "да", и теперь ищут для способа выставить частные интерфейсы своих классов в своих тестовых наборах.</p> <p>мой ответ основан на наблюдении тонкого факта: вы уже опробовали свои частные методы. следуя подходу "красный-зеленый-рефакторинг", распространенному в разработке, управляемой тестами, вы создали открытые api-интерфейсы ваших объектов для выполнения работы, которую должны выполнять эти объекты. благодаря этой работе, указанной в тестах, и продолжающемуся выполнению тестов, гарантирующим, что вы ничего не сломали, вы можете организовать внутреннюю систему ваших классов по своему усмотрению.</p> <p>ваши частные методы уже протестированы, потому что все, что вы делаете, это рефакторинг поведения, для которого у вас уже есть тесты. вы никогда не должны попадать в ситуацию, когда закрытый метод не проверен или не полностью протестирован, потому что вы создаете их только тогда, когда видите возможность очистить реализацию открытых методов. это гарантирует, что частные методы существуют только для поддержки классов, которые они должны вызывать во время тестирования, потому что они определенно вызываются из открытых методов.</p> </blockquote>

<p>если вы не хотите распределять свои реализации частных методов по нескольким исходным файлам, уточнение к решению "категория" заключается в определении расширения (по существу, анонимной категории - см. <a href="http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/chapters/occategories.html">документация apple</a> ) в заголовочном файле. это импортируется как реализацией вашего существующего класса, так и соответствующими исходными файлами модульного теста.</p><p>использование расширения позволяет компилятору предупредить вас, если реализация основного метода отсутствует в основном блоке @implementation. <a href="http://lisles.net/accessing-private-methods-and-properties-in-objc-unit-tests/">эта ссылка</a> это хорошо иллюстрирует.</p>

<p>легкая работа. шаги: 1. у вас есть - (nsstring *) getteststring; в вашей целевой файл м для интерфейса foo</p><ol start="2"> <li> <p>добавьте категорию в свой файл модульного теста:</p> <p>@interface demohomeviewcontroller () - (nsstring *) getteststring; @конец</p> </li> </ol><p>тогда делай что хочешь сейчас.</p>