Как проверить код, который зависит от UIUserInterfaceIdiom (IOS)

У меня есть некоторый код Objective C [i-os], который я хотел бы запустить модульные тесты с использованием XCode. Он получает доступ к различным метаданным в зависимости от типа устройства, используя:

[[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad

У меня проблема в том, что когда я запускаю модульные тесты, этот результат всегда верен. В идеале было бы замечательно иметь возможность установить его во время выполнения теста.

Я предполагаю, что это можно сделать, создав класс, который инкапсулирует проверку устройства и макетирует ее для теста. Но я подумал, что стоит посмотреть, есть ли лучшие решения.

Для справки: хороший пост в блоге со множеством ссылок, руководство по тестированию Apple Unit и пример кода Code Unit.

1 ответ

Решение

Я попробовал несколько разных подходов этим утром:

  1. Используя UIDevice категория, которая связана только с моей целью теста. В этой категории я бы переопределил currentDevice с partialMock реализация (OCMock) и заглушить необходимый метод, чтобы он принудительно возвращал Pad или Phone моим тестам. У него должна быть работа, но его очень трудно связать с такими классами, как UIDevice или же UIApplicationсимулятор часто падает, что является плохим знаком.

  2. #undef UI_INTERFACE_IDIOM() а также #define это на моем тесте .pch, Указав UI_INTERFACE_IDIOM() реализация в тесте для моего собственного экземпляра, который я мог бы установить соответственно на Pad или Phone. Это сработало, но основная проблема заключается в том, что при запуске тестов симулятор также работает (тесты приложений), поэтому, если вы запускаете свои тесты на iPad, ваш тест пройдет, но другие части симулятора не пройдут, потому что противоречивых ответов он получает от UI_INTERFACE_IDIOM() (одна из них - загрузка пера, специфичного для iPhone, если вы находитесь в универсальной среде приложений)

  3. Я думаю, что это лучший подход. Как и все в информатике, просто добавьте еще один слой =) Вместо вашего кода, используя UI_INTERFACE_IDIOM() чтобы оценить, находится ли он на устройстве Pad или Phone, инкапсулируйте эту логику в объект, который вы можете смоделировать во время ваших тестов. Сюда UI_INTERFACE_IDIOM() все еще будет доступен для остальной части симулятора. Ваш производственный код на самом деле будет опираться на него, но ваши тесты будут опираться на заглушенную реализацию, которая может отвечать ожидаемым в ваших тестах.

Если вы хотите, я могу поделиться некоторыми кодами по этому вопросу. И да, это утомительно!

Как вам удалось обойти это?

Другие вопросы по тегам