OCUnit 应用程序测试:尝试测试 UIPageControl numberOfPages == NSArray count

Posted

技术标签:

【中文标题】OCUnit 应用程序测试:尝试测试 UIPageControl numberOfPages == NSArray count【英文标题】:OCUnit application testing: Trying to test UIPageControl numberOfPages == NSArray count 【发布时间】:2011-12-12 10:41:21 【问题描述】:

我对 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]);

日志显示匹配的整数值,查看页面和 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 显示viewedPages 计数与我创建的模拟数组的计数相匹配(太棒了!)但 numberOfPages 始终为零?结果,测试失败。

我还尝试将在控制器中加载viewedPages数组的函数与测试控制器中的一个本地函数混合,该函数返回一个预定义的数组,即,

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

但是,这与上面的结果完全相同。测试仍然失败,因为 numberOfPages 返回 0,而viewedPages 数组显示了预期的计数。

正如我所说,我是 OCUnit 和 OCMock 的新手,所以我希望这个问题尽可能详细并且有意义。我希望这归结为我对 OCMock 如何工作的误解,有人可以纠正我 - 我将永远感激!不幸的是,对于 iPhone 开发的 OCUnit 和 OCMock 来说,似乎确实缺乏像样的文档供初学者学习,这个小问题已经让我发疯了两天......

提前谢谢你

【问题讨论】:

您已经在mock 中模拟了您的控制器,但您仍在对您的controller 进行操作,它们是两个不同的对象。 谢谢保罗。不过我还是有点困惑,希望您能详细说明一下,因为如果它们是两个不同的对象,我不明白为什么控制器的viewedPages 计数与我为Mock 对象设置的(新)计数相匹配?在没有创建模拟的情况下,我有两条记录。当我模拟对象并调动 loadViewedPages 方法时,控制器和模拟都显示三个记录,如果它们是不同的对象,我会感到惊讶。同样,这绝对是我的误解,我发现的文档对我没有帮助。干杯! 我刚刚尝试了以下方法,但结果仍然相同[mock viewDidLoad]; NSLog(@"%d", [[mock pageControl] numberOfPages]); NSLog(@"%d", [[mock chefs] count]); 对此感到非常困惑,感谢任何帮助 【参考方案1】:

您的controller.pageControl 很可能为零。这可能是因为它没有连接到 IBOutlet 或以其他方式初始化,或者因为您的单元测试实际上并未在应用程序可执行文件中运行。查看setting up your unit test target 中的步骤并检查您的设置。

或者,您可以模拟 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];

【讨论】:

非常感谢 - 这正是我在一大早通过测试所采用的方法!但是,我也设法最终使用 STAssertTrue (如我发布的原始方法)运行测试。为此,我在测试函数中创建了一个 UIPageControl 的本地实例,并将控制器存根以使用本地 PageControl 而不是控制器中的那个。一旦我有了,所有的计数都正确计算了。 (我一直试图用 OCMock 版本交换它,但结果我只需要创建一个真正的本地版本!)

以上是关于OCUnit 应用程序测试:尝试测试 UIPageControl numberOfPages == NSArray count的主要内容,如果未能解决你的问题,请参考以下文章

OCUnit - iOS 5 - 如何在我的应用程序中测试文件?

如何使用 Xcode 4 和 OCUnit 运行应用程序测试?

访问 OCUnit 测试目标中的 UIImage

如何从命令行在 iPhone 上启动 OCUnit 测试

如何捕获 OCUnit 测试通过/失败消息/事件

iPhone 上的 ocunit 测试