아래 매크로는 http://dadabeatnik.wordpress.com/2013/09/12/xcode-and-asynchronous-unit-testing/ 에서 찾은 내용입니다.


// Macro - Set the flag for block completion

#define StartBlock() __block BOOL waitingForBlock = YES


// Macro - Set the flag to stop the loop

#define EndBlock() waitingForBlock = NO


// Macro - Wait and loop until flag is set

#define WaitUntilBlockCompletes() WaitWhile(waitingForBlock)


// Macro - Wait for condition to be NO/false in blocks and asynchronous calls

// Each test should have its own instance of a BOOL condition because of non-thread safe operations

#define WaitWhile(condition) \

do { \

while(condition) { \

[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; \

} \

} while(0)




사용 예제


페이스북의 문자로 된 ID를 숫자 형태의 ID로 바꿀 때 사용하는 facebook의 graph api 조회를 예로 들어보겠습니다.


비동기로 수행되는 로직이 있는경우 해당 로직이 끝나기 전에 테스트 케이스가 끝나버리기 때문에 위의 매크로를 이용해서 비동기 처리가 끝날 때 까지 테스트 케이스가 종료되지 않도록 기다립니다.


주의할 점은 비동기 로직이 실패했을 때에도 EndBlock();을 호출 해 주어야 정상적으로 종료 됩니다.


- (void)testFacebookURL {

NSString *urlString = @"https://graph.facebook.com/사용자 또는 페이지 아이디";

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

manager.responseSerializer = [AFJSONResponseSerializer serializer];


StartBlock();

[manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {

NSLog(@"response : %@", responseObject);

NSLog(@"id : %@", responseObject[@"id"]);


EndBlock();


} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

NSLog(@"Error : %@", error);

EndBlock();

}];

WaitUntilBlockCompletes();

}


+ Recent posts