Как перья iPhone можно тестировать с помощью логических тестов?
Модульное тестирование View Controllers представляется очень важной частью разработки iPhone ( см. Эту статью). Это, однако, требует инициализации контроллеров от пера, что я считаю невозможным сделать правильно в логическом тесте.
Загрузка ресурсов из пакета (см. Этот вопрос) в логическом тесте работает нормально. Даже загрузка перьев возможна так:
UntitledViewController* controller = [[UntitledViewController alloc]initWithNibName:nil bundle:[NSBundle bundleForClass:[self class]]];
, Это, однако, работает только до тех пор, пока перо содержит только UIViews. Другие представления (я пробовал UITableView и UISwitch) приводят к сбою проверки с кодом 138.
Можно ли проверить мои перья с помощью логических тестов, и если да, то как?
2 ответа
Это зависит от того, что вы пытаетесь проверить. Если вы хотите убедиться, что ваши привязки настроены правильно, прочитайте статью Криса Хансона о модульном тестировании вашего интерфейса Какао. Лично я считаю, что это излишне, и приводит к увеличению количества тестового кода, который не очень полезен. Но это только мои 2 цента.
Если вы на самом деле попытаетесь взаимодействовать с этими элементами интерфейса в своем тесте, вы, как вы обнаружили, даже столкнетесь с множеством ошибок тестирования, особенно с UIActionSheets и UITableViews.
Но ваша цель должна состоять в модульном тестировании поведения вашего контроллера, а не поведения объектов пользовательского интерфейса Apple. То, что я нашел, работает лучше всего - это использовать OCMock для макета элементов UI и проверки того, что контроллер выполняет ожидаемые вызовы на них. Вот пара примеров:
-(void)testClickingAButtonHidesAView {
//setup
id mockViewToHide = [OCMockObject mockForClass:[UIView class]];
[[mockViewToHide expect] setHidden:YES];
[controller setSomeView:mockViewToHide];
// hideButtonClicked is an IBAction that is the hide button's target
[controller hideButtonClicked];
[mockViewToHide verify];
}
-(void)testActionSheetPublishClick {
// ModelManager is the controller's dependency, which publishes Items
id mockModelManager = [OCMockObject mockForClass:[ModelManager class]];
[controller setModelManager:mockModelManager];
// this doesn't really need to be mocked, but it's a convenient way to create
// a reference you can validate in expect:
id mockItem = [OCMockObject mockForClass:[Item class]];
[controller setCurrentItem:mockItem];
// when the user clicks "Publish" (the first button on the action sheet),
// the controller should publish the current item
[[mockModelManager expect] publishItem:mockItem];
// stub object so I know which action sheet was clicked
id mockPublishActionSheet = [OCMockObject mockForClass:[UIActionSheet class]];
[controller setPublishConfirmation:mockPublishActionSheet];
// simulate action sheet click
[controller actionSheet:mockPublishActionSheet didDismissWithButtonIndex:0];
[mockModelManager verify];
}
Вместо этого используйте тесты приложений и управляйте своим пользовательским интерфейсом на устройстве.