2011-02-01 6 views
4

Je construis une petite bibliothèque pour gérer les opérations de téléchargement et de téléchargement de fichiers pour moi et j'essaie d'y intégrer une suite de tests. Plutôt que d'utiliser des méthodes de rappel des délégués, je traitais les réponses asynchrones dans un bloc de gestionnaire d'achèvement comme ceci:Rappel de bloc asynchrone 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); 
    }]; 

La méthode uploadFileWithFilename... sous-jacente est comme ceci:

- (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]; 
} 

je vis one example où le gars était l'utilisation d'un préprocesseur définit et injecte l'OCMock dans la base de code actuelle. Cela me semble faux.

Quelle serait la meilleure stratégie pour tester un morceau de code comme celui-ci?

+0

Dans la fonction ci-dessus, que signifie chemin échappé correctement? – Namratha

Répondre

1

Cette réponse n'est pas liée spécifiquement à OCMock il ne peut pas être ce que vous cherchez, mais ...

je ferais quelque chose comme ceci:

__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... 

De cette façon, vous bloquer jusqu'à ce que l'un des rappels se soit frayé un chemin jusqu'à la boucle d'exécution principale.