2013-09-21 10 views
0

비동기 코드에 TDD를 적용하는 동안 배포 대상에서 작동하는 동일한 코드가 테스트 대상에서 작동하지 않는다는 것을 알았습니다.테스트 대상 및 배포 대상에서 비동기 코드의 다른 동작

- (void)testReceivingLocation 
{ 
    locationManager = [[CLLocationManager alloc] init]; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
    locationManager.delegate = self; 
    locationManager.pausesLocationUpdatesAutomatically = NO; 
    if ([CLLocationManager locationServicesEnabled]) 
    { 
     [locationManager startUpdatingLocation]; 
    } 
    startLocation = nil; 

    NSDate *until = [NSDate dateWithTimeIntervalSinceNow:10]; 
    while ([until timeIntervalSinceNow] > 0) 
    { 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
           beforeDate:until]; 
    } 
    XCTAssert(alreadyReceivedLocation, @"Location wasn't received."); 
} 

-(void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
      fromLocation:(CLLocation *)oldLocation 
{ 
    alreadyReceivedLocation = true; 
    // Never actually get there. 
} 

무슨 문제가 될 수있다 :이 문제의 예 하나는 내가 CLLocationManager를 사용하여 발견?

답변

0

[SomeClass performActionWithAsyncResponse]가 작업을 수행하는 방법에 대해 좀 더 자세히 설명해야합니다.

완료 대기열의 블록에서 completionWithResult가 호출된다고 가정하면 테스트 메소드가 완료된 후 스레드가 종료되기 때문에이 작업이 수행되지 않습니다. 프로덕션 환경에서는 앱이 계속 실행되기 때문에 그렇지 않습니다.

일반적으로 테스트에서 주 대기열을 다시 호출하는 비동기 호출을 기다리는 코드를 사용합니다.

NSDate *until = [NSDate dateWithTimeIntervalSinceNow:30]; 
while ([loopUntil timeIntervalSinceNow] > 0) 
{ 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
          beforeDate:until]; 
} 

비동기 작업이 수행되었는지 여부를 나타내는 조건으로 while 루프를 중지 할 수도 있습니다 (예 : 테스트 속성 사용).

비동기 테스트 패턴에 대한 자세한이 게시물을 참조 : 포인터에 대한 Pattern for unit testing async queue that calls main queue on completion

+0

감사합니다! 내가 사용하는 특정 메서드로 질문을 업데이트하고 sleep() 대신 코드를 사용하려고했습니다. 불행히도, 아무 것도 바뀌지 않았습니다 ... – Sergey

+0

Ah, CLLoactionManager 시뮬레이터에서 위치 업데이트가 없다고 생각합니다. GPS 수정 프로그램이있는 장치에서 테스트를 실행할 수 있습니까? CLLocationManager는 시뮬레이터에서 약간 다르게 동작합니다. – sofacoder