2011-02-01 97 views
4

我正在構建一個小型庫來處理文件上傳和下載操作,並試圖將一套測試集成到它中。而不是使用委託回調方法,我處理異步響應的完成處理程序塊,像這樣:OCMock異步塊回調

SyncKit *engine = [[SyncKit alloc] init]; 
    NSURL *localFilePath = [NSURL URLWithString:@"/Users/justin/Desktop/FileTest.png"]; 

    [engine uploadFileWithFilename:@"FileTest.png" toRemotePath:@"/" fromLocalPath:localFilePath withCompletionHandler:^(id response, NSError *error) { 
    if (error) 
    { 
     NSLog(@"error = %@", error); 
     return; 
    } 

    NSLog(@"File uploaded and return JSON response = %@", response); 
    }]; 

底層uploadFileWithFilename...方法是像這樣:

- (void)uploadFileWithFilename:(NSString *)filename toRemotePath:(NSString *)remotePath fromLocalPath:(NSURL *)localPath withCompletionHandler:(SKCompletionHandler)handler 
{ 
    if ((![[NSFileManager defaultManager] fileExistsAtPath:[localPath path]])) 
    { 
    NSDictionary *userInfo = [NSDictionary dictionaryWithObject:localPath forKey:@"localPath"]; 
    NSError *error = [NSError errorWithDomain:SKDropboxErrorDomain code:SKDropboxErrorFileNotFound userInfo:userInfo]; 
    handler(nil, error); 
    return; 
    } 

    // path is the directory the file will be uploaded to, make sure it doesn't have a trailing/
    // (unless it's the root dir) and is properly escaped 
    NSString *trimmedPath; 
    if (([remotePath length] > 1) && ([remotePath characterAtIndex:[remotePath length] - 1] == '/')) 
    { 
    trimmedPath = [remotePath substringToIndex:[remotePath length] - 1]; 
    } 
    else if ([remotePath isEqualToString:@"/"]) 
    { 
    trimmedPath = @"//"; 
    } 
    else 
    { 
    trimmedPath = remotePath; 
    } 

    NSString *escapedPath = [NSString escapePath:trimmedPath]; 
    NSString *fullPath = [NSString stringWithFormat:@"/files/dropbox%@", escapedPath];  
    NSString *urlString = [NSString stringWithFormat:@"%@://%@/%@%@", kSKProtocolHTTPS, kSKDropboxAPIContentHost, kSKDropboxAPIVersion, fullPath]; 

    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:filename, @"file", nil]; 
    NSString *body = [params convertToURIParameterString]; 

    NSURL *url = nil; 
    if ([body length] == 0) 
    { 
    url = [NSURL URLWithString:[NSString stringWithFormat:@"%@", urlString]]; 
    } 
    else 
    { 
    url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", urlString, body]]; 
    } 

    __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url]; 
    request.delegate = self; 
    request.requestMethod = kSKMethodPOST; 

    [request addFile:[localPath path] forKey:@"file"]; 

    // 
    // Dropbox uses OAuth to handle its authentication, so we need to pass along the requested 
    // tokens and secrets so that we get our stuff back. 
    // 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    NSString *token = [defaults objectForKey:@"oauth_token"]; 
    NSString *secret = [defaults objectForKey:@"oauth_secret"]; 

    [request buildPostBody]; 
    NSData *authBody = request.postBody; 

    NSString *header = OAuthorizationHeader(url, request.requestMethod, authBody, kOAuthConsumerKey, kOAuthConsumerSecret, token, secret); 
    [request addRequestHeader:@"Authorization" value:header]; 

    [request setCompletionBlock:^{ 
    NSDictionary *result = (NSDictionary *)[[request responseString] JSONValue];  
    [self.activeUploads removeObjectForKey:remotePath]; 
    handler(result, nil); 
    }]; 

    [request setFailedBlock:^{ 
    NSError *error = request.error; 
    [self.activeUploads removeObjectForKey:remotePath]; 
    handler(nil, error); 
    }]; 

    [self.activeUploads setObject:request forKey:remotePath]; 

    [self.queue addOperation:request]; 
} 

我看到one example其中傢伙使用預處理器定義並將OCMock注入到實際的代碼庫中。這對我來說似乎是錯誤的。

測試這樣一段代碼的最佳策略是什麼?

+0

在上面的函數中,正確的轉義路徑是什麼意思? – Namratha 2011-05-26 11:29:34

回答

1

所以它可能不是你要尋找這個答案是不相關專門OCMock,但是......

我會做這樣的事情:

__block BOOL testPassed = NO; 

[engine uploadFileWithFilename:@"FileTest.png" 
        toRemotePath:@"/" 
       fromLocalPath:localFilePath 
     withCompletionHandler:^(id response, NSError *error) { 
    if (error) 
    { 
     return; 
    } 

    testPassed = YES; 
    }]; 

[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode 
         beforeDate:[[NSDate date] dateByAddingTimeInterval:10]]; 

// make sure that testPassed is YES... 

這樣,你會阻止,直到其中一個回調進入主運行循環。