2011-02-01 62 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... 

这样,你会阻止,直到其中一个回调进入主运行循环。