2015-02-07 4 views
0

Я начинаю в модульное тестирование с Objective-C, и мне нужно знать, как проверить блоки с OCMockito и Xcode 6.Испытательные блоки с Xcode 6 и OCMockito

Я тестирует Interactor, это Interactor должен возвращать array как аргумент блока, и я должен спросить файл Provider для элементов.

Это метод, который я хочу, чтобы тест:

- (void)userPoiListsWithSuccessBlock:(MNBSavePoisInteractorSuccess)success { 
     self.poiListEntityArray = [self.poiListProvider poiListsForUser:self.loggedUser]; 
     self.poiListViewObjectArray = [self viewPoiListObjectListWithPoiLists:self.poiListEntityArray]; 
     success(self.poiListViewObjectArray); 
    } 

Во-первых, я могу настроить элементы, которые я собираюсь использовать

self.mockPoiListProvider = mock([PoiListProvider class]); 
    self.sut = [[MNBSavePoisInteractor alloc] initWithManagedObjectContext:self.coreDataStack.managedObjectContext andPoiListProvider:self.mockPoiListProvider]; 

- (UserEntity *)loggedUserMock { 
    UserEntity *mockLoggedUser = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([UserEntity class]) inManagedObjectContext:self.coreDataStack.managedObjectContext]; 
    [email protected]"1"; 
    [email protected]"user"; 
    [email protected]; 
    return mockLoggedUser; 
} 

- (InMemoryCoreDataStack *)coreDataStack{ 
    if (!_coreDataStack) { 
     _coreDataStack = [[InMemoryCoreDataStack alloc] init]; 
    } 
    return _coreDataStack; 
} 

- (PoiListEntity *)poiListFake { 
    PoiListEntity *fake = [NSEntityDescription insertNewObjectForEntityForName:@"PoiListEntity" inManagedObjectContext:self.coreDataStack.managedObjectContext]; 
    fake.name = @"Test"; 
    fake.poisCount = @2; 
    [fake addContributorsObject:[self loggedUserMock]]; 

    return fake; 
} 

Затем я делаю тест. Я использую Xcode 6 waitForExpectation для управления асинхронными методами. Я думаю, что я делаю что-то неправильно.

- (void)waitForExpectation { 
    [self waitForExpectationsWithTimeout:5.0 handler:^(NSError *error) { 
     if (error) { 
      NSLog(@"Timeout Error: %@", error); 
     } 
    }]; 
} 
- (void)testShouldReturnPoiLists { 
    XCTestExpectation *expectation = [self expectationWithDescription:@"Waiting method ends"]; 

    [given([self.mockPoiListProvider poiListsForUser:[self loggedUserMock]]) willReturn:@[[self poiListFake]]]; 

    [self.sut userPoiListsWithSuccessBlock:^(NSArray *results) { 
     [expectation fulfill]; 
      XCTAssert(resutls.count == 1, @"Results %zd", resutls.count); 
    }]; 
    [self waitForExpectation]; 
} 

Я понял, если я дам объект в willReturn в данном методе, когда я вызываю метод SUT, что я хочу, чтобы проверить это должно вернуть то, что я даю раньше. Это правда? Спасибо

+0

Я не понимаю намерений вашей стороны, потому что я не понимаю намерения тестируемого метода. Можете ли вы объяснить, что такое '-userPoiListsWithSuccessBlock:' и что вы хотите проверить? –

+0

Извините @JonReid, на самом деле это был не настоящий метод. Я обновил его. Этот метод возвращает массив '' 's. Массив имеет два типа объектов, которые соответствуют протоколу . Метод 'PoiListProvider' возвращает элементы Entity. Второй метод возвращает '', которые являются «Ponsos», которые я конвертирую из сущностей и трех пользовательских объектов. Я хочу проверить, имеет ли массив результатов столько же объектов, сколько мне нужно. Я думал, что если я установлю 'willReturn' с этим сущностью, я поймаю это в блоке. Я сожалею, что не понимаю, что я должен делать с этими тестами. – croigsalvador

ответ

1

Я не вижу асинхронного кода. Вам просто нужен блок, который фиксирует результаты, поэтому используйте переменную __block, чтобы сделать результаты доступными вне блока. Тогда вы можете утверждать, что вы хотите:

- (void)testShouldReturnPoiLists { 
    [given([self.mockPoiListProvider poiListsForUser:[self loggedUserMock]]) willReturn:@[[self poiListFake]]]; 
    __block NSArray *capturedResults; 

    [self.sut userPoiListsWithSuccessBlock:^(NSArray *results) { 
     capturedResults = results; 
    }]; 

    assertThat(capturedResults, hasLengthOf(1)); 
} 

Взаимосвязь между длиной 1 и подделка, трудно сказать. Давайте также параметризуем код фальсификации:

- (PoiListEntity *)poiListFakeWithName:(NSString *)name count:(NSNumber *)count { 
    PoiListEntity *fake = [NSEntityDescription insertNewObjectForEntityForName:@"PoiListEntity" inManagedObjectContext:self.coreDataStack.managedObjectContext]; 
    fake.name = name; 
    fake.poisCount = count; 
    [fake addContributorsObject:[self loggedUserMock]]; 
    return fake; 
} 

С этим мы можем написать более интересные тесты.

Я хочу добавить, что важно «слушать тесты». У Core Data очень много запутанной настройки. Это говорит мне, что если вы можете переписать вещи независимо от Core Data - совершенно не зная об этом - все будет намного проще.

+0

Извините @JonReid, я был очень занят, и я не мог попробовать, но это сработало. У меня есть один новый вопрос: что мне делать Если 'poiListProvider' вызывает метод с блоком, который дает мне« NSArray », и это« результат NSArray », который я передаю как параметр в' successBlock'? Что я должен тестировать в интеракторе? Должен ли я проверить его вызов метода poiList, когда я вызываю «useror userPoiListWith ...»? Должен ли я проверить возвращаемый параметр в блоке? Мне очень жаль, но я не очень хорошо это понимаю. Если вы предпочитаете, я могу опубликовать новый вопрос. Спасибо – croigsalvador

+0

Да, новый вопрос, вероятно, будет полезен. –

 Смежные вопросы

  • Нет связанных вопросов^_^