Тестирование приложения OCUnit: попытка протестировать UIPageControl numberOfPages == NSArray count

Я относительно новичок в OCUnit и OCMock, поэтому, пожалуйста, потерпите меня. У меня есть контроллер представления, который содержит UIPageControl, где количество страниц рассчитывается на основе количества NSArray (который заполняется из основных данных). Это делается в методе ViewDidLoad следующим образом:

- (void)ViewDidLoad {
    [super viewDidLoad];

    ... other code ...

    self.pageControl.numberOfPages = [self.viewedPages count];
    self.pageControl.currentPage = 0;

    NSLog(@"%d", controller.pageControl.numberOfPages);
    NSLog(@"%d", [controller.viewedPages count]);
}

В журнале отображаются совпадающие целочисленные значения как для ViewPages, так и для numberOfPages, и, к счастью, если я запущу приведенный ниже тест, утверждение будет верным:

- (void)testPageControl {
    [controller viewDidLoad];
    STAssertTrue(controller.pageControl.numberOfPages == [controller.viewedPages count], @"...");
}

Однако, как уже упоминалось, этот процесс основан на использовании массива с объектами из Core Data, поэтому я решил попробовать свои силы в OCMock, чтобы заменить его предварительно заданным массивом, чтобы эффективно удалить элемент Core Data. При этом я теперь получаю результаты, которых не понимаю.

Вот как выглядит мой новый тест:

- (void)testPageControl {
    id mock = [OCMockObject partialMockForObject:controller];
    NSArray *mockPagesArray = [NSArray alloc] initWithObjects:...];
    [[[mock stub] andReturn:mockPagesArray] viewedPages];

    [controller viewDidLoad];

    NSLog(@"%d", [controller.pageControl numberOfPages]);
    NSLog(@"%d", [controller.viewedPages count]);
    STAssertTrue(controller.pageControl.numberOfPages == [controller.viewedPages count], @"...");
    [mockPagesArray release];
}

Что меня смущает, так это то, что в этом сценарии NSLog показывает, что количество просмотренных страниц соответствует количеству созданного мной фиктивного массива (отлично!), Но numberOfPages всегда равно нулю? В результате тест провален.

Я также попытался использовать функцию, которая загружает массив ViewPages в контроллер, с локальной функцией в тестовом контроллере, которая возвращает предварительно определенный массив, т.е.

[[[mock stub] andCall:@selector(createMockPageViews) onObject:self] loadPageViews];

Однако это имело точно такой же результат, как и выше. Тест по-прежнему терпит неудачу, потому что numberOfPages возвращает 0, в то время как массив visiblePages показывает ожидаемое количество.

Как я уже сказал, я новичок в OCUnit и OCMock, поэтому я надеюсь, что этот вопрос будет максимально подробным и имеет смысл. Я надеюсь, что это связано с моим непониманием того, как работает OCMock, и кто-то может меня исправить - я буду бесконечно благодарен! Кажется, что на OCUnit и OCMock для разработки iPhone действительно не хватает достойной документации для начинающих, к сожалению, и эта небольшая проблема сводит меня с ума уже два дня...

заранее спасибо


person Shane Henderson    schedule 12.12.2011    source источник
comment
Вы сделали макет своего контроллера в mock, но вы все еще работаете на своем controller, это два разных объекта.   -  person Paul.s    schedule 12.12.2011
comment
Спасибо, Пол. Я все еще немного запутался и надеюсь, что вы сможете уточнить, потому что, если это два разных объекта, я не понимаю, почему количество просмотренных страниц контроллера соответствует (новому) количеству, которое я установил для объекта Mock? Без создания макета у меня есть две записи. Когда я издеваюсь над объектом и использую метод loadViewedPages, контроллер и макет показывают три записи, что меня удивляет, если это разные объекты. Опять же, это определенно будет связано с недоразумением с моей стороны, и документация, которую я нашел, мне не помогла. Ваше здоровье!   -  person Shane Henderson    schedule 12.12.2011
comment
Я только что попробовал следующее, но все равно те же результаты [mock viewDidLoad]; NSLog(@"%d", [[mock pageControl] numberOfPages]); NSLog(@"%d", [[mock chefs] count]); Действительно запутался в этом и ценю любую помощь   -  person Shane Henderson    schedule 12.12.2011


Ответы (1)


Ваш controller.pageControl, скорее всего, равен нулю. Это может быть связано с тем, что он не подключен к IBOutlet или иным образом инициализирован, или потому, что ваши модульные тесты на самом деле не выполняются в исполняемом файле приложения. Взгляните на шаги в настройте цель модульного теста и проверьте свои настройки.

В качестве альтернативы вы можете издеваться над объектом UIPageControl:

- (void)testPageControl {
    id mockPageControl = [OCMockObject mockForClass:[UIPageControl class]];
    [[mockPageControl expect] setNumberOfPages:3];
    [[mockPageControl expect] setCurrentPage:0];

    id mock = [OCMockObject partialMockForObject:controller];
    NSArray *mockPagesArray = [NSArray alloc] initWithObjects:...];
    [[[mock stub] andReturn:mockPagesArray] viewedPages];
    [[[mock stub] andReturn:mockPageControl] pageControl];

    [controller viewDidLoad];

    [mockPageControl verify];
}
person Christopher Pickslay    schedule 12.12.2011
comment
Большое спасибо - это именно тот подход, который я использовал в самые ранние утренние часы, чтобы сдать тест! Тем не менее, мне также удалось, наконец, запустить тест, используя STAssertTrue (как и в исходном методе, который я опубликовал). Для этого я создал локальный экземпляр UIPageControl в тестовой функции и заглушил контроллер, чтобы использовать локальный PageControl вместо того, который находится в контроллере. Все подсчеты сошлись правильно, как только у меня это было. (Я пытался заменить его версией OCMock, но оказалось, что мне просто нужно было создать настоящую локальную версию!) - person Shane Henderson; 13.12.2011