2011-01-14 2 views
1

컨트롤러 클래스에있는 IBoutlet이 모두 NIB 파일에 올바르게 연결되었는지 단위 테스트로 확인하고 싶습니다. OCMock으로 이것을하고 싶습니다. 비록 컨트롤러 변수가 NIB를로드 한 후에 nil이 아니라는 것을 간단히 선언 할 수 있다는 것을 알고 있습니다. 이것은 프로세스가 어떻게 작동하는지에 대한 일반적인 이해의 문제입니다. 이해한다면, 이것이 효과가 있어야합니다.OCMock을 통한 IBOutlet 연결 확인

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에 실제로 올바른 개체가 포함되어 있는지 확인하기 위해 세 가지 추가 어설 션을 넣습니다. 실제 컨트롤러의 인스턴스에 넣으면 OK입니다. 그러나 위의 그림과 같이 모의를 사용하면 멀리까지 이해할 수 없습니다. 대신, 시험이에 충돌 :

 
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:을 중단하고보고합니다.

무엇이 여기에 있습니까?

답변

0

기본 시스템 스레드에서 실행 해 보셨습니까? 주 스레드에서 UIKit 클래스를 인스턴스화 할 수 없습니다.

- (BOOL)shouldRunOnMainThread { 
    /* Tell GHUnit to run on a separate thread */ 
    return YES; 
} 
+0

불행히도, 차이는 없습니다. –

-1

당신은 실제로 유닛 테스트에서 시각적 물건을 할 캔트 : GTM 그것을 않지만, GHUnit 당신이 당신의 테스트 케이스 클래스에 다음과 같이 넣을 수있는 방법을 확실하지. 뷰는 실제로로드되지 않습니다. 또한 awakeAfterUsingCoder이 호출되는지 테스트 할 필요가 없습니다. 애플의 물건. 일반적으로 단위 테스트는 논리를 테스트해야합니다. Apple의 코드이기 때문에 awakeAfterUsingCoder이 init에서 호출되었다고 가정 할 수 있습니다. 당신은 당신의 메소드가 호출되었는지 확인해야합니다.