我想通过单元测试验证IBoutlet我的控制器类中的所有 s 是否正确连接到 NIB 文件中。我想用 OCMock 来做这件事——即使我知道我可以简单地断言控制器变量不在nil加载 NIB 之后。这更多的是对流程如何工作的一般理解 - 据我所知,这也应该有效。
NIBOnOffSwitchCell作为其 File's Owner OnOffSwitchCellController。这是我的测试方法:
- (void) testIBOutletCellIsWiredToXib {
id mockController = [OCMockObject mockForClass:[OnOffSwitchCellController class]];
[[mockController expect] awakeAfterUsingCoder:OCMOCK_ANY];
[[mockController expect] setValue:OCMOCK_ANY forKey:@"cell"];
[[mockController expect] setValue:OCMOCK_ANY forKey:@"thelabel"];
[[mockController expect] setValue:OCMOCK_ANY forKey:@"theswitch"];
NSArray* nibContents = [guiBundle loadNibNamed:@"OnOffSwitchCell"
owner:mockController
options:nil];
assertThat(nibContents, isNot(nil));
assertThatInt([nibContents count], is(equalToInt(1)));
assertThat([nibContents objectAtIndex:0], is(instanceOf([OnOffSwitchCell class])));
[mockController verify];
}
guiBundle存在并被验证为有效的 NSBundle 对象。
据我了解loadNibNamed:owner:options:将反序列化NIB中的对象,调用awakeAfterUsingCoder:然后通过调用setValue:forKey:每个出口来设置出口。
我又添加了三个断言,以确保加载的 NIB 实际上包含正确的对象——当我放入真实控制器的实例时,这些断言通过了。但是当我使用如上所示的模拟时,它甚至没有走到这一步。相反,测试会因此崩溃:
测试用例“-[OnOffSwitchCellControllerTestCase testIBOutletCellIsWiredToXib]”已启动。
2011-01-14 10:48:35.364 GTMTest[67797:903] *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,
原因:'OCMockObject [OnOffSwitchCellController]:
调用了意外的方法:awakeAfterUsingCoder:<UINibDecoder: 0x500e800>
预期:setValue:<OCMAnyConstraint:0x4c718e0> forKey:@"cell"
预期:setValue:<OCMAnyConstraint:0x4c71ce0> forKey:@"thelabel"
预期:setValue:<OCMAnyConstraint:0x4c71ed0> forKey:@"theswitch"'
*** 第一次抛出调用堆栈:
(
0 核心基础 0x00e3dbe9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f925c2 objc_exception_throw + 47
2 核心基础 0x00e3db21 -[NSException 引发] + 17
3 GTMTest 0x0001a049 -[OCMockObject 句柄UnRecordedInvocation:] + 322
4 GTMTest 0x00019aca-[OCMockObject forwardInvocation:] + 77
5 核心基础 0x00daf404 ___转发___ + 1124
6 核心基础 0x00daef22 _CF_forwarding_prep_0 + 50
7 UIKit 0x0062394a UINibDecoderDecodeObjectForValue + 2438
8 UIKit 0x00624693-[UINibDecoder decodeObjectForKey:] + 398
9 UIKit 0x0053cf43-[UIRuntimeConnection initWithCoder:] + 212
10 UIKit 0x0053d4b1-[UIRuntimeEventConnection initWithCoder:] + 64
11 UIKit 0x006239e4 UINibDecoderDecodeObjectForValue + 2592
12 UIKit 0x006232dc UINibDecoderDecodeObjectForValue + 792
13 UIKit 0x00624693-[UINibDecoder decodeObjectForKey:] + 398
14 UIKit 0x0053c200 -[UINib 实例化WithOwner:选项:] + 804
15 UIKit 0x0053e081-[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 168
16 GTMTest 0x000140dc-[OnOffSwitchCellControllerTestCase 测试IBOutletCellIsWiredToXib] + 503
17 GTMTest 0x000041f3 -[SenTestCase 调用测试] + 163
18 GTMTest 0x0000479a -[GTMTestCase 调用测试] + 146
19 GTMTest 0x00003e90 -[SenTestCase 执行测试] + 37
20 GTMTest 0x00002f3d -[GTMIPhoneUnitTestDelegate runTests] + 1413
21 GTMTest 0x000028fb -[GTMIPhoneUnitTestDelegate applicationDidFinishLaunching:] + 197
22 UIKit 0x00347253-[UIApplication_callInitializationDelegatesForURL:payload:suspended:] + 1252
23 UIKit 0x0034955e-[UIApplication_runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 439
24 UIKit 0x00348ef0 -[UIApplication_run] + 452
25 UIKit 0x0035542e UIApplicationMain + 1160
26 GTMTest 0x00003500 主要 + 104
27 GTMTest 0x0000273d 开始 + 53
28 ???0x00000002 0x0 + 2
)
在抛出“NSException”实例后调用终止
因此awakeAfterUsingCoder:,尽管我显然预料到了,但它却在抱怨这个电话是出乎意料的。
我还尝试消除这种期望并用一个不会报告多余方法调用的漂亮模拟替换模拟,但它仍然会中止并报告setValue:forKey:没有被调用。
我在这里想念什么?