2014-11-19 4 views
1

우리는 모든 뷰 컨트롤러를 개별적으로 테스트하기 위해 커스텀 단위 테스트를 작성하려고합니다. UI 자동화, KIF 및 기타 솔루션이 있다는 것을 알고 있지만 위의 코드를 살펴보면 사용하지 않고도 가능하다는 것을 알게 될 것입니다.뷰 컨트롤러 테스트를위한 단위 테스트 작성 방법은 무엇입니까?

간단히 말해서 두 개의 공용 메소드 "setFirstState"및 "setSecondState"가있는 간단한보기 컨트롤러가 있다고 가정합니다. 필자는 뷰 컨트롤러가 완전히 인스턴스화되고 화면에 표시 될 때 호출되는 "setFirstState"메서드가 필요합니다 (viewDidLoad를 거침).

@interface MyViewController 

    - (void)setFirstState; 
    - (void)setSecondState; 

@end 

@implementation MyViewController 

    - (void)viewDidLoad { 

    [super viewDidLoad]; 

    [self setFirstState]; 
    } 

@end 

그래서, 테스트 setFirstState 호출에 대한 단위 테스트 (XCTest 및 OCMock 사용)처럼 보일 수 있습니다 : 여기 데모보기 컨트롤러의

- (void)test_viewDidLoad_CallsMyMethod { 

    MyViewController *viewContoller = [[MyViewController alloc] init]; 

    id mock = [OCMockObject partialMockForObject:viewContoller]; 
    [[mock expect] showLogin]; 

    [UIApplication sharedApplication].keyWindow.rootViewController = (MyViewController *)mock; 

    [mock verify]; 
} 

흥미로운 코드 라인의 ViewController에 모의 할당 한 (이다)를 keyWindow의 rootViewController에 전달합니다. 우리는 viewDidLoad, viewWillAppear 메소드가 호출되기를 원할 경우이를 수행 할 필요가 있음을 발견했습니다. 그렇지 않으면 호출되지 않습니다. 그러나 테스트를 실행하면 시뮬레이터가이 행에 멈 춥니 다. Xcode는 실행 중이며 아직 살아 있지만 더 이상 진행되지 않음을 보여줍니다.

또한 viewDidLoad를 시뮬레이션하고 테스트하기 위해 keyWindow의 rootViewController 코드 행을 "[mock viewDidLoad]"로 바꾸려고 시도했지만 중단됩니다. 그래서, 그것은 부분적인 조롱 것처럼 보이는 컨트롤러의 내부 흐름을 깰 것처럼 보입니다.

mock을 제거하고 뷰 컨트롤러를 keyWindow의 rootViewController에 직접 할당하면 작동하고 다른 모든 것들을 테스트 할 수 있습니다. 그러나 어쩌면 누구나 우리가 그 문제를 어떻게 해결할 수 있을지 생각할 수 있습니까?

업데이트 우리는 시스템의 모든 구성 요소가 느슨하게 결합되도록 Storyboards 대신 Xibs를 사용합니다.

+0

view 속성에 액세스하면 viewDidLoad가 호출됩니다. 해당 메소드에 대한 실제 테스트에서 viewWillAppear 등을 호출하면됩니다. – InsertWittyName

+0

Nop, keyWindow의 rootViewController 코드 줄을 "UIView * view = [모의보기];"로 바꿉니다. 도움이 안돼. 그것은 또한 달려있다. – Centurion

답변

0

NewRelic 라이브러리가 OCMock을 위반하고있는 것으로 판명되었습니다. :). 따라서 모든 것을 주석으로 처리 한 후 작동합니다.

//[NewRelicAgent startWithApplicationToken:@"token"];