Я хочу проверить с помощью модульных тестов, что все IBoutlet
в моем классе контроллера правильно подключены в файле NIB.Я хотел бы сделать это с OCMock - хотя я знаю, что мог бы просто утверждать, что переменные контроллеров не nil
после загрузки NIB.Это скорее вопрос общего понимания того, как работает процесс - насколько я понимаю, это тоже должно работать.
NIB OnOffSwitchCell
имеет в качестве владельца файла 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 на самом деле содержит правильные объекты - они проходят нормально, когда я вставляюЭкземпляр настоящего контроллера.Но когда я использую макет, как показано выше, он даже не заходит так далеко.Вместо этого тест дает сбой с этим:
Test Case '-[OnOffSwitchCellControllerTestCase testIBOutletCellIsWiredToXib]' started.
2011-01-14 10:48:35.364 GTMTest[67797:903] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'OCMockObject[OnOffSwitchCellController]:
unexpected method invoked: awakeAfterUsingCoder:<UINibDecoder: 0x500e800>
expected: setValue:<OCMAnyConstraint: 0x4c718e0> forKey:@"cell"
expected: setValue:<OCMAnyConstraint: 0x4c71ce0> forKey:@"thelabel"
expected: setValue:<OCMAnyConstraint: 0x4c71ed0> forKey:@"theswitch"'
*** Call stack at first throw:
(
0 CoreFoundation 0x00e3dbe9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f925c2 objc_exception_throw + 47
2 CoreFoundation 0x00e3db21 -[NSException raise] + 17
3 GTMTest 0x0001a049 -[OCMockObject handleUnRecordedInvocation:] + 322
4 GTMTest 0x00019aca -[OCMockObject forwardInvocation:] + 77
5 CoreFoundation 0x00daf404 ___forwarding___ + 1124
6 CoreFoundation 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 instantiateWithOwner:options:] + 804
15 UIKit 0x0053e081 -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 168
16 GTMTest 0x000140dc -[OnOffSwitchCellControllerTestCase testIBOutletCellIsWiredToXib] + 503
17 GTMTest 0x000041f3 -[SenTestCase invokeTest] + 163
18 GTMTest 0x0000479a -[GTMTestCase invokeTest] + 146
19 GTMTest 0x00003e90 -[SenTestCase performTest] + 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 main + 104
27 GTMTest 0x0000273d start + 53
28 ??? 0x00000002 0x0 + 2
)
terminate called after throwing an instance of 'NSException'
Так что он жаловался на вызов awakeAfterUsingCoder:
как на неожиданный, хотя я явно ожидал его.
Я также пытался удалить это ожиданиеи заменой макета на хороший макет, который не будет сообщать о лишних вызовах методов, но затем он все еще прерывает и сообщает, что setValue:forKey:
не вызывается.
Что мне здесь не хватает?