ios – 如何在UIViewController中对UICollectionView进行单元测试

前端之家收集整理的这篇文章主要介绍了ios – 如何在UIViewController中对UICollectionView进行单元测试前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想对UIVollection视图中的UICollectionView进行单元测试(例如,我想测试UICollectionView是否具有我希望它在单元测试中具有的单元格数)

我的单元测试基于以下博客(关于如何对视图控制器进行单元测试):
http://yetanotherdevelopersblog.blogspot.co.il/2012/03/how-to-test-storyboard-ios-view.html

在单元测试中,我能够在我正在测试的UIViewController中获得指向UICollectionView的指针.这是我的测试的setUp方法中的代码

storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"MainViewController"];
[viewController performSelectorOnMainThread:@selector(loadView) withObject:nil waitUntilDone:YES];
self.collectionView = viewController.collectionView

不幸的是,这个UICollectionView中没有单元格(即self.collectionView.visibleCells.count等于0,因此我无法访问单元格并测试数据是我期望的那样),虽然在调试时我可以看到我的应用程序将这些单元格添加到集合视图.

我究竟做错了什么?
任何提示&关于如何在UIViewController中单元测试UICollectionView的技巧?

编辑:
在Roshan的帮助之后,我现在可以缩小我的问题范围了.我正在测试一个有UICollectionView的UIViewController.在我的单元测试中,我想测试CollectionView中的单元格值是我期待它的.但是,我的ViewController上没有调用collectionView:cellForItemAtIndexPath:因此当我作为单元测试调用它时,我的单元格不存在.任何的想法?

解决方法

在iOS上实现TTD时,尽量不要依赖系统调用委托和数据源方法.

您应该直接从单元测试中调用这些方法.这只是为您的测试配置合适的环境的问题.

例如,当我为UICollectionView实现TDD时,我创建两个独立的类专门用于实现UICollectionViewDataSource和UICollectionViewDelegate协议创建一个关注点分离,我可以单独测试这些类到视图控制器本身,虽然我仍然需要初始化查看控制器以设置视图层次结构.

这是一个例子,当然省略了标题和其他小部分代码.

UICollectionViewDataSource示例

@implementation CellContentDataSource

@synthesize someModelObjectReference = __someModelObjectReference;

#pragma mark - UICollectionViewDataSource Protocol implementation

- (NSInteger) collectionView:(UICollectionView *)collectionView
  numberOfItemsInSection:(NSInteger)section
{
    return __someModelObjectReference ? 
         [[__someModelObjectReference modelObjects] count] : 0;
}

- (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView
               cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString * const kCellReuseIdentifer =   @"Cell";
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellReuseIdentifer forIndexPath:indexPath];

    ModelObject *modelObject = [__someModelObjectReference modelObjects][[indexPath item]];

    /* VarIoUs setter methods on your cell with the model object */

    return cell;
}
@end

单元测试示例

- (void) testUICollectionViewDataSource
{
    UIStoryBoard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    MainViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"MainViewController"];
    [viewController view]; // Loads the view hierarchy

    // Using OCMock to mock the returning of the model objects from the model object reference.
    // The helper method referenced builds an array of test objects for the collection view to reference
    id modelObjectMock = [OCMockObject mockForClass:[SomeModelObjectReference class]];
    [[[modelObjectMock stub] andReturn:[self buildModelObjectsForTest]] modelObjects];

    CellContentDataSource *dataSource = [CellContentDataSource new];
    dataSource.someModelObjectReference = modelObjectMock;
    viewController.collectionView.dataSource = dataSource;

    // Here we call the data source method directly
    UICollectionViewCell *cell = [dataSource collectionView:viewController.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];

    XCTAssertNotNil(cell,@"Cell should not be nil");
    // Assert your cells contents here based on your test model objects
}

猜你在找的iOS相关文章