使用 OCMock 测试 NSWidowController
Posted
技术标签:
【中文标题】使用 OCMock 测试 NSWidowController【英文标题】:Testing NSWidowController using OCMock 【发布时间】:2011-04-11 13:43:52 【问题描述】:我一直在尝试想出一种方法来使用 OCMock 对我的 applicationDidFinishLaunching 委托进行单元测试。我的 NSWindowController 在这里被实例化,我想测试一下。这是我的测试代码:
id mockWindowController = [OCMockObject niceMockForClass:[URLTimerWindowController class]];
[[mockWindowController expect] showWindow:self];
NSUInteger preRetainCount = [mockWindowController retainCount];
[appDelegate applicationDidFinishLaunching:nil];
[mockWindowController verify];
当我运行测试时,我得到了错误:
“OCMockObject[URLTimerWindowController]:预期的方法没有被调用:showWindow:-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]”
日志提供了更多细节:
"Test Case '-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]' started.
2011-04-11 08:36:57.558 otest-x86_64[3868:903] -[URLTimerWindowController loadWindow]: failed to load window nib file 'TimerWindow'.
Unknown.m:0: error: -[URLTimerAppDelegateTests testApplicationDidFinishLaunching] : OCMockObject[URLTimerWindowController]: expected method was not invoked: showWindow:-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]
Test Case '-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]' failed (0.005 seconds).
"
所以我看到 NIB 无法加载。好的,那么我如何在单元测试时加载它或以某种方式模拟它的负载?我已经查看了 OCMock 文档、Chris Hanson 的单元测试技巧以及其他一些资源,包括以类似方式运行的 WhereIsMyMac 源代码。我用于实例化窗口控制器的应用程序是这样的:
self.urlTimerWindowController = [[URLTimerWindowController alloc] init];
[self.urlTimerWindowController showWindow:self];
非常感谢任何提示。
【问题讨论】:
尝试测试保留计数是没有意义的。我添加了一些常见的标签,以便可以回答特定问题的人可以看到这个。 是的,测试保留计数对我来说也很愚蠢。我从 WhereIsMyMac 示例代码和单元测试中得到了它,然后把它留在里面。我想先尝试让事情正常工作,然后我会从那里减少事情,但马上,我遇到了这个问题。 你从哪里得到的示例代码?有网址吗?我抓住了我在谷歌看到的第一件事,并没有看到所说的代码。 从这里:cocoawithlove.com/2009/12/… 谢谢——我在那里留下了一条评论,指出该代码中retainCount
的使用被破坏了。不幸的是,我不知道这个具体问题的答案。
【参考方案1】:
您的测试的问题是mockWindowController
和urlTimerWindowController
不是同一个对象。并且您测试中的self
与被测类中的self
不同。在这种情况下,笔尖不加载并不重要。
当对象在您要测试的方法中实例化时,您通常不能模拟它。一种替代方法是在一种方法中实例化对象,然后将其传递给完成设置的另一种方法。然后您可以测试设置方法。例如:
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
self.urlTimerWindowController = [[URLTimerWindowController alloc] init];
[self setUpTimerWindow:urlTimerWindowController];
-(void)setUpTimerWindow:(URLTimerWindowController *)controller
[controller showWindow:self];
然后,您将测试setUpTimerWindow:
:
-(void)testSetUpTimerWindowShouldShowWindow
URLTimerAppDelegate *appDelegate = [[URLTimerAppDelegate alloc] init];
id mockWindowController = [OCMockObject niceMockForClass:[URLTimerWindowController class]];
[[mockWindowController expect] showWindow:appDelegate]; // this seems weird. does showWindow really take the app delegate as a parameter?
[appDelegate setUpTimerWindow:mockWindowController];
[mockWindowController verify];
[appDelegate release];
【讨论】:
以上是关于使用 OCMock 测试 NSWidowController的主要内容,如果未能解决你的问题,请参考以下文章
xcode 中的单元测试(使用 GHUnit 和 OCMock)