和Xcode 6和OCMockito
我与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方法。真的吗? 谢谢
我看不到异步代码。您只需要一个可捕获结果的块,因此请使用__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上跳舞。这告诉我,如果你可以重写独立于核心数据的东西 - 完全不知道它 - 一切都会更简单。
对不起@JonReid,我很忙,我无法尝试,但它的工作。我有一个新问题,我应该怎么做如果'poiListProvider'调用带有'block'的方法,该方法给了我一个'NSArray',那就是我在'successBlock'中作为参数传递的'result NSArray'?我应该在交互器中测试什么?当我调用'interactctor userPoiListWith ...'时,我应该验证他是否调用poiList方法?我应该在块中测试返回的参数吗?我很抱歉,但我不太清楚。如果您愿意,我可以发布一个新问题。谢谢 – croigsalvador 2015-03-05 23:28:50
是的,一个新问题可能会有帮助。 – 2015-03-06 03:33:19
我不明白你的测试方的意图,因为我不明白被测方法的意图。你能解释一下'-userPoiListsWithSuccessBlock:'是什么,你想测试什么? – 2015-02-07 20:54:22
对不起@JonReid,实际上这不是真正的方法。我已经更新了它。这个方法返回一个''的数组。该阵列有两种符合协议的对象。 PoiListProvider方法返回实体项目。第二种方法返回'',它们是我从实体和三个自定义对象转换而来的'Ponsos'。我想测试结果数组是否具有我需要的相同数量的对象。我想如果我用这个实体设置'willReturn',我会在该块中捕获它。我很抱歉,我不明白我应该怎么做这个测试 –
croigsalvador
2015-02-09 19:48:48