2015-02-07 78 views
0
测试块

我与Objective-C的单元测试开始,我需要知道如何与OCMockito和Xcode的6和Xcode 6和OCMockito

我测试的交互器试块,这个交互器应该返回一个数组作为块参数,我必须要求提供者文件中的元素。

这是我要测试的方法:

- (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:'是什么,你想测试什么? – 2015-02-07 20:54:22

+0

对不起@JonReid,实际上这不是真正的方法。我已经更新了它。这个方法返回一个''的数组。该阵列有两种符合协议的对象。 PoiListProvider方法返回实体项目。第二种方法返回'',它们是我从实体和三个自定义对象转换而来的'Ponsos'。我想测试结果数组是否具有我需要的相同数量的对象。我想如果我用这个实体设置'willReturn',我会在该块中捕获它。我很抱歉,我不明白我应该怎么做这个测试 – croigsalvador 2015-02-09 19:48:48

回答

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上跳舞。这告诉我,如果你可以重写独立于核心数据的东西 - 完全不知道它 - 一切都会更简单。

+0

对不起@JonReid,我很忙,我无法尝试,但它的工作。我有一个新问题,我应该怎么做如果'poiListProvider'调用带有'block'的方法,该方法给了我一个'NSArray',那就是我在'successBlock'中作为参数传递的'result NSArray'?我应该在交互器中测试什么?当我调用'interactctor userPoiListWith ...'时,我应该验证他是否调用poiList方法?我应该在块中测试返回的参数吗?我很抱歉,但我不太清楚。如果您愿意,我可以发布一个新问题。谢谢 – croigsalvador 2015-03-05 23:28:50

+0

是的,一个新问题可能会有帮助。 – 2015-03-06 03:33:19