2010-07-16 2 views
0

단위 테스트를 쓰고 있습니다. 이 keyWindowUIApplication의 속성/내부 가치를 조롱하는 방법?

UIWindow* window = [UIApplication sharedApplication].keyWindow; 

를 호출하고 keyWindow (나는 모든 창없는) 전무를 반환하기 때문에 그리고, 하나 개의 기능을 테스트 할 수 없습니다. 하지만 아무것도 돌려 줄 필요는 없지만 아무 것도하지 않아도됩니다.

나는 카테고리를 사용하여 수동으로 keyWindow 값을 설정하지만,이

당신이 내 자리에 어떻게 할 것인지
@interface UIApplication(UnitTest) 
- (id)getKeyWindow; 
@end 

@implementation UIApplication(UnitTest) 
- (id)getKeyWindow 
{ 
    return [self keyWindow]; 
} 
@end 

// compiler error: lvalue required as left operand of assignment 
[[UIApplication sharedApplication] getKeyWindow] = [[UIWindow alloc] init]; 

를 작동하지 않았다?

답변

3

애플은 프레임 워크 클래스에 가까워지면 코드를 테스트하기 쉽지 않습니다. UIApplication은 특히 싱글 톤 속성과 프레임 워크가 설치 과정에서 인스턴스를 생성한다는 점 때문에 어렵습니다. 이와 같은 문제에 대한 해결책은 일반적으로 테스트 방법에 따라 다릅니다. 예를 들어, 테스트에 유효한 UIApplication 객체가 있습니까? OCUnit을 사용하고 있다면, 테스트 대상이 애플리케이션 번들에서 실행되도록 설정하지 않았다면 ([UIApplication sharedApplication] 자체가 nil을 리턴 할 수도 있습니다.

하나의 옵션은 이것을 단순히 테스트하지 않는 것입니다. 대부분 메인 윈도우와의 상호 작용은 비교적 간단하며,이 코드의 테스트는 자신의 코드만큼 UIKit 프레임 워크를 테스트합니다. 이는 코드를 어떻게 구성했는지,이 작은 영역을 테스트하지 않고 (또는 더 적절하게는 자동 테스트를하지 않고) 남겨 두는 것이 얼마나 편하며, 테스트를 작성하는 것이 얼마나 어려울 지에 따라 문법적으로 결정됩니다.

테스트해야 할 UIWindow 개체와 관련된 코드가있는 경우 테스트 할 수있는 방식으로 기능을 캡슐화하는 것이 좋습니다. 사용자 정의 메서드에서 UIWindow 객체를 반환하는 응용 프로그램의 UIApplication 하위 클래스를 만들어이 작업을 수행 할 수 있습니다. 코드에서이 메서드를 직접 사용하지 말고 테스트에서 직접이 메서드를 재정 의하여 원하는대로 반환하십시오.

0

위임 개체를 조롱하고 응용 프로그램 대리인 설정자를 사용하여 applicationDidBecomeActive와 같은 특정 기대치를 확인할 수있었습니다. 대신

id<UIApplicationDelegate> delegate = [MyCustomDelegate alloc] init]; 
UIApplication *app = [UIApplication alloc] init]; 
app.delegate = delegate; 
//results in "There can only be one UIApplication" error 

:

@implementation AppDelegateTests { 

- (void)testAppDelegate { 
    //perform swizzle on [UIApplication class] and method @selector(setDelegate:) with 
    //[self class] and at the bottom @selector(swizzledSetDelegate:) 

    id<UIApplicationDelegate> delegate = [MyCustomDelegate alloc] init]; 

    //Here's the magic, this line actually calls [UIApplication setDelegate] and not the swizzledSetDelegate method below. 
    //If you don't understand this, look up how swizzling works and hopefully you can wrap your head around it. The logic is quite mind-bendy. 
    [self swizzledSetDelegate:delegate]; 

    //here set up your mock on the delegate and verify state of things 
} 

- (void)swizzledSetDelegate:(id<UIApplicationDelegate>)delegate { 
    //do nothing 
} 

} 

참고이 예제는 내가 테스트하는 데 필요한 무엇을, 당신은 당신이 조롱 할 일에 대해 그 경우에도 가능하면 생각해야하는 것은 매우 정의입니다.

관련 문제