Как проверить код, который зависит от UIUserInterfaceIdiom (IOS)
У меня есть некоторый код Objective C [i-os], который я хотел бы запустить модульные тесты с использованием XCode. Он получает доступ к различным метаданным в зависимости от типа устройства, используя:
[[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad
У меня проблема в том, что когда я запускаю модульные тесты, этот результат всегда верен. В идеале было бы замечательно иметь возможность установить его во время выполнения теста.
Я предполагаю, что это можно сделать, создав класс, который инкапсулирует проверку устройства и макетирует ее для теста. Но я подумал, что стоит посмотреть, есть ли лучшие решения.
Для справки: хороший пост в блоге со множеством ссылок, руководство по тестированию Apple Unit и пример кода Code Unit.
1 ответ
Я попробовал несколько разных подходов этим утром:
Используя
UIDevice
категория, которая связана только с моей целью теста. В этой категории я бы переопределилcurrentDevice
сpartialMock
реализация (OCMock
) и заглушить необходимый метод, чтобы он принудительно возвращал Pad или Phone моим тестам. У него должна быть работа, но его очень трудно связать с такими классами, какUIDevice
или жеUIApplication
симулятор часто падает, что является плохим знаком.#undef UI_INTERFACE_IDIOM()
а также#define
это на моем тесте.pch
, УказавUI_INTERFACE_IDIOM()
реализация в тесте для моего собственного экземпляра, который я мог бы установить соответственно на Pad или Phone. Это сработало, но основная проблема заключается в том, что при запуске тестов симулятор также работает (тесты приложений), поэтому, если вы запускаете свои тесты на iPad, ваш тест пройдет, но другие части симулятора не пройдут, потому что противоречивых ответов он получает отUI_INTERFACE_IDIOM()
(одна из них - загрузка пера, специфичного для iPhone, если вы находитесь в универсальной среде приложений)Я думаю, что это лучший подход. Как и все в информатике, просто добавьте еще один слой =) Вместо вашего кода, используя
UI_INTERFACE_IDIOM()
чтобы оценить, находится ли он на устройстве Pad или Phone, инкапсулируйте эту логику в объект, который вы можете смоделировать во время ваших тестов. СюдаUI_INTERFACE_IDIOM()
все еще будет доступен для остальной части симулятора. Ваш производственный код на самом деле будет опираться на него, но ваши тесты будут опираться на заглушенную реализацию, которая может отвечать ожидаемым в ваших тестах.
Если вы хотите, я могу поделиться некоторыми кодами по этому вопросу. И да, это утомительно!
Как вам удалось обойти это?