所以我有一个课,我写了一些测试用例。这个类有以下两种方法:
- (void)showNextNewsItem {
self.xmlUrl = self.nextNewsUrl;
[self loadWebViewContent];
}
- (void)showPreviousNewsItem {
self.xmlUrl = self.previousNewsUrl;
[self loadWebViewContent];
}
可以重构,这是非常原始的,但我只是想确保下一次加载下一次和之前的加载。所以我使用OCMock为我的SUT类实例化OCMockObject
,如下所示:
- (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
。当然,这不是预期的,因为我在测试中,我只期望在生产代码本身中发生某些事情。
嘲讽概念的哪一部分我不理解?
答案 0 :(得分:2)
模拟被测试的类通常会让人感到困惑,但是如果你想这样做,你需要一个“部分模拟”,这样你就可以调用方法而不需要对它们进行存根并让它们执行常规方法。
根据docs,这似乎在OCMock中得到支持。
答案 1 :(得分: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];
}