2014-07-10 2 views
2

OCMock을 사용하여 스토리 보드에서 인스턴스화 된 UIViewController를 테스트하고 있습니다. 모범 사례에 따르면 뷰 컨트롤러보기의 하위 뷰 IBOutlet은 모두 weak 속성입니다. 테스트가 약한 속성에 의존하는 메서드를 호출하는 뷰 컨트롤러에 대한 테스트를 작성할 때, 내가 첨부 된 것과 같이 산발적 인 EXC_BAD_ACCESS 충돌을 보게됩니다.OCMock - 부분적으로 조롱 된 개체의 약한 속성에 액세스하면 산발적 인 사고가 발생합니다.

단위 테스트를 실행할 때마다 충돌이 발생하지 않습니다. 패턴이없는 것처럼 보입니다. 크래시 표면이든 아니든 완전히 무작위입니다. 뷰 컨트롤러를 부분적으로 조롱하는 디자인 기법은 앱의 여러 위치에서도 사용됩니다.

무슨 일이 벌어 질 수 있습니까? 내가 여기서하려고하는 것에 충돌이 있습니까?

@interface CustomUIViewControllerTests : XCTestCase 

@property (nonatomic, strong) CustomUIViewController *vc; 
@property (nonatomic, strong) UIStoryboard *mainStoryboard; 

@end 

@implementation CustomUIViewControllerTests 

- (void)setUp 
{ 
    [super setUp]; 

    // In order to test data on the Storyboard - need to instantiate the Storyboard 
    self.mainStoryboard = [UIStoryboard storyboardWithName:[[NSBundle mainBundle].infoDictionary 
                  objectForKey:@"UIMainStoryboardFile"] 
                bundle:[NSBundle mainBundle]]; 

    self.vc = [_mainStoryboard instantiateViewControllerWithIdentifier:kStoryboardVCID]; 
    [self.vc loadView]; 
} 

- (void)testSomething 
{ 
    id mockController = [OCMockObject partialMockForObject:self.vc]; 
    [mockController doSomethingThatUsesAWeakProperty]; 
    //other verification/assertions here 
} 

크래시

: 여기

Process:   XXXX [33756] 
Path:   /Users/USER/Library/Application Support/iPhone Simulator/*/XXXX.app/XXXX 
Identifier:  XXXX 
Version:   0 
Code Type:  X86-64 (Native) 
Parent Process: launchd_sim [33727] 
Responsible:  launchd_sim [33727] 
User ID:   501 

Date/Time:  2014-07-10 11:51:51.692 -0400 
OS Version:  Mac OS X 10.9.3 (13D65) 
Report Version: 11 
Anonymous UUID: 8B81673C-B92D-28D3-9940-47C83C140C8E 


Crashed Thread: 0 Dispatch queue: com.apple.main-thread 

Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: KERN_INVALID_ADDRESS at 0x000000011ab0e360 

External Modification Warnings: 
Debugger attached to process. 

VM Regions Near 0x11ab0e360: 
    MALLOC_TINY   0000000114700000-0000000114800000 [ 1024K] rw-/rwx SM=PRV 
--> 
    JS JIT generated code 0000056193e99000-0000056193e9a000 [ 4K] ---/rwx SM=NUL 

Application Specific Information: 
iPhone Simulator 463.9.41, iPhone OS 7.1 (iPhone Retina (4-inch 64-bit)/11D167) 


Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 
0 libsystem_kernel.dylib    0x0000000103156292 __kill + 10 
1 XXXX        0x000000010010f565 CLSSignalHandler + 218 (CLSSignal.m:305) 
2 libsystem_platform.dylib   0x00000001030295aa _sigtramp + 26 
3 Foundation       0x0000000102174225 -[NSConcreteValue getValue:] + 29 
4 Foundation       0x00000001021af5be -[NSValue nonretainedObjectValue] + 25 
5 XXXX        0x0000000100153e00 +[OCPartialMockObject existingPartialMockForObject:] + 160 (OCPartialMockObject.m:50) 
6 XXXX        0x00000001001546e1 -[OCPartialMockObject forwardingTargetForSelectorForRealObject:] + 65 (OCPartialMockObject.m:170) 
7 CoreFoundation      0x0000000102a8ba5c ___forwarding___ + 156 
8 CoreFoundation      0x0000000102a8b938 _CF_forwarding_prep_0 + 120 
9 XXXX        0x0000000100028ea6 -[CustomUIViewController doSomethingThatUsesAWeakProperty] + 454 (CustomUIViewControllerTests.m:121) 
10 CoreFoundation      0x0000000102a8ff1c __invoking___ + 140 
11 CoreFoundation      0x0000000102a8fdc4 -[NSInvocation invoke] + 308 
12 CoreFoundation      0x0000000102a8ff86 -[NSInvocation invokeWithTarget:] + 54 
13 XXXX        0x0000000100154999 -[OCPartialMockObject handleUnRecordedInvocation:] + 73 (OCPartialMockObject.m:217) 
14 XXXX        0x0000000100151fe6 -[OCMockObject forwardInvocation:] + 102 (OCMockObject.m:190) 
15 CoreFoundation      0x0000000102a8bb85 ___forwarding___ + 453 
16 CoreFoundation      0x0000000102a8b938 _CF_forwarding_prep_0 + 120 
17 XXXXTests       0x000000010c0d289d -[CustomUIViewControllerTests testSomething] + 573 (CustomUIViewControllerTests.m:996) 
18 CoreFoundation      0x0000000102a8ff1c __invoking___ + 140 
19 CoreFoundation      0x0000000102a8fdc4 -[NSInvocation invoke] + 308 
20 XCTest        0x0000000109ba4c40 -[XCTestCase invokeTest] + 161 
21 XCTest        0x0000000109ba4d2c -[XCTestCase performTest:] + 91 
22 XCTest        0x0000000109ba5a75 -[XCTest run] + 65 
23 XCTest        0x0000000109ba44df -[XCTestSuite performTest:] + 125 
24 XCTest        0x0000000109ba5a75 -[XCTest run] + 65 
25 XCTest        0x0000000109ba44df -[XCTestSuite performTest:] + 125 
26 XCTest        0x0000000109ba5a75 -[XCTest run] + 65 
27 XCTest        0x0000000109ba44df -[XCTestSuite performTest:] + 125 
28 XCTest        0x0000000109ba5a75 -[XCTest run] + 65 
29 XCTest        0x0000000109ba71b4 +[XCTestProbe runTests:] + 138 
30 Foundation       0x00000001021846dc __NSFireDelayedPerform + 354 
31 CoreFoundation      0x0000000102a5cc34 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20 
32 CoreFoundation      0x0000000102a5c7b2 __CFRunLoopDoTimer + 962 
33 CoreFoundation      0x0000000102a457be __CFRunLoopRun + 1614 
34 CoreFoundation      0x0000000102a44d83 CFRunLoopRunSpecific + 467 
35 GraphicsServices     0x00000001039dcf04 GSEventRunModal + 161 
36 UIKit        0x00000001010cce33 UIApplicationMain + 1010 
37 XXXX        0x000000010007b889 main + 169 (main.m:16) 
38 libdyld.dylib      0x000000010301f5fd start + 1 
+0

나는 이것이 관련이있을 수 있습니다 생각 : http://stackoverflow.com/questions/9104544/how-can-i-get-ocmock-under-arc-to-stop-nilling-an-nsproxy- subclass-set-using-aw – tdeegan

+0

"뷰 컨트롤러를 부분적으로 조롱하는이 디자인 기법은 앱의 여러 위치에서 사용됩니다." 테스트 도중 호출되는 메서드로 설정되고이 충돌을 볼 수없는 몇 가지 레이블에 약한 참조로 간단한 테스트를 만들었습니다. 아직. –

답변

0

문제는 partialMock를 만들 때 OCMock가 무엇과 관련이있다. 소스 코드 here을 확인할 수 있습니다.

그것은 당신의 ViewController의 관점 밖으로 nilled되고 있다는 것, 그리고 그것으로, 그것은 모두 (콘센트로 설정) 파단

하지만이 중요하다입니다 : 일반적으로 당신이 테스트중인 다른 객체가 아닌 시스템을 조롱 . SUT를 조롱하는 경우 코드를 리팩토링해야한다는 신호 일 수 있습니다.

그런 말은, 예를 들어 게으른 인스턴스 생성 속성에서 모의 ​​객체를 반환하는 것과 같은 일을하기 위해 부분 모의를 사용하여 SUT를 조롱합니다.