У меня есть ряд классов Objective C, организованных в иерархии наследования.Все они имеют общего родителя, который реализует все поведение, разделяемое между детьми.Каждый дочерний класс определяет несколько методов, которые заставляют его работать, и родительский класс вызывает исключение для методов, предназначенных для реализации / переопределения его дочерними классами.Это фактически делает родительский класс псевдо-абстрактным классом (поскольку он сам по себе бесполезен), хотя Objective-C не поддерживает явно абстрактные классы.
Суть этой проблемы заключается в том, что я тестирую этот модульиерархия классов с использованием OCUnit, и тесты структурированы аналогично: один тестовый класс, который выполняет общее поведение, с подклассом, соответствующим каждому из тестируемых дочерних классов.Тем не менее, запуск тестовых случаев в (эффективно абстрактном) родительском классе проблематичен, поскольку модульные тесты не пройдут эффектным образом без ключевых методов.(Альтернатива повторения общих тестов для 5 классов тестов на самом деле не является приемлемой.)
Неидеальное решение, которое я использовал, заключается в проверке (в каждом методе тестирования), является ли экземплярродительский тестовый класс, и выручить, если это так.Это приводит к повторному коду в каждом методе тестирования, и эта проблема становится все более раздражающей, если у вас очень детальные юнит-тесты.Кроме того, все такие тесты по-прежнему выполняются и сообщаются как об успешных, искажая количество значимых тестов, которые фактически были запущены.
Я бы предпочел, чтобы это был сигнал OCUnit "Не запускайте никаких тестовв этом классе запускайте их только в дочерних классах. "Насколько мне известно, пока нет способа сделать это, что-то похожее на +(BOOL)isAbstractTest
метод, который я могу реализовать / переопределить.Есть идеи, как лучше решить эту проблему с минимальным повторением?Имеет ли OCUnit какую-либо возможность пометить тестовый класс таким образом, или пора подать радар?
Редактировать: Вот ссылка на тестовый кодпод вопросом .Обратите внимание на частое повторение if (...) return;
для запуска метода, включая использование макроса NonConcreteClass()
для краткости.