3

所以我有一堂课,我写了一些测试用例。这个类有这两个方法:

- (void)showNextNewsItem {
    self.xmlUrl = self.nextNewsUrl;
    [self loadWebViewContent];
}

- (void)showPreviousNewsItem {
    self.xmlUrl = self.previousNewsUrl;
    [self loadWebViewContent];
}

可以重构,这是非常原始的,但是我只想确保下一个加载下一个和上一个加载之前。所以我使用 OCMockOCMockObject为我的 SUT 类实例化一个,如下所示:

- (void)testShowNextOrPreviousItemShouldReloadWebView {

    id mockSut = [OCMockObject mockForClass:[NewsItemDetailsViewController class]];

    [[[mockSut expect] andReturn:@"http://www.someurl.com"] nextNewsUrl];
    [[mockSut expect] loadWebViewContent];

    [[[mockSut expect] andReturn:@"http://www.someurl.com"] previousNewsUrl];
    [[mockSut expect] loadWebViewContent];

    [mockSut showNextNewsItem];
    [mockSut showPreviousNewsItem];

    [mockSut verify];
}

问题在于这两行实际上调用了要验证的方法。OCMock 现在告诉我,调用showNextNewsItem并且showPreviousNewsItem不是预期的。当然,这不是预期的,因为我正在测试中,我只希望在生产代码本身中发生某些事情。

我没有正确理解嘲笑概念的哪一部分?

4

2 回答 2

2

模拟被测类通常会令人困惑,但如果你想这样做,你需要一个“部分模拟”,这样你就可以调用方法而不用存根它们并让它们执行正常的方法。

根据文档,这似乎在 OCMock 中得到支持。

于 2013-01-19T18:09:17.433 回答
2

我找到了解决方案。在对象上使用 partialMock 正是我想要的。这样,我明确定义的调用会被模拟,并且我会在“未模拟”对象上调用正在测试的方法。

- (void)testShowNextOrPreviousItemShouldReloadWebView {

    NewsItemDetailsViewController *sut = [[NewsItemDetailsViewController alloc] init];

    id mockSut = [OCMockObject partialMockForObject:sut];

    [[[mockSut expect] andReturn:@"http://www.someurl.com"] nextNewsUrl];
    [[mockSut expect] loadWebViewContent];

    [[[mockSut expect] andReturn:@"http://www.someurl.com"] previousNewsUrl];
    [[mockSut expect] loadWebViewContent];

    [sut showNextNewsItem];
    [sut showPreviousNewsItem];

    [mockSut verify];
}
于 2013-01-19T18:13:15.730 回答