OCMock asynchronous block callback

I am creating a small library for processing files and uploading files for me, and I am trying to integrate a test suite into it. Instead of using delegate callback methods, I process asynchronous responses in the completion handler block as follows:

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

The main uploadFileWithFilename... method looks like this:

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

I saw one example where a guy used a preprocessor to identify and inject OCMock into the actual code base. This seems to me wrong.

What would be the best strategy for checking code?

+4
source share
1 answer

This answer is not specifically related to OCMock, so it may not be what you are looking for, but ...

I would do something like this:

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

That way, you would block until one of the callbacks gets into the main loop of the loop.

+1
source

Source: https://habr.com/ru/post/1337988/


All Articles