Unit testing Parse framework iOS

后端 未结 3 714

I am attempting to write unit tests for an iOS application which makes use of the Parse backend framework, and after much experimentation seem to be failing at writing succe

3条回答
  •  -上瘾入骨i
    2020-12-18 09:49

    If you don't mind to utilize a third party library, you may use the following approach:

    #import 
    #import 
    ...
    
    @interface PFUserTests : XCTestCase
    @end
    
    @implementation PFUserTests
    
    // helper:
    - (RXPromise*) saveUser:(User*)user {
        RXPromise* promise = [[RXPromise alloc] init];
        [PFUser saveUser:user withBlock:^(Bool success, NSError*error){
            if (success) {
                [promise fulfillWithValue:@"OK"];
            }
            else {
                [promise rejectWithReason:error];
            }
        }];
        return promise;
    }
    
    
    // tests:
    
    -(void) testSaveUser 
    {
        User* user = ... ;
        RXPromise* promise = [self saveUser:user];
    
        // set a timeout:
        [promise setTimeout:5.0];
    
        [promise.thenOn(dispatch_get_main_queue(), ^id(id result) {
            XCTAssertTrue([result isEqualToString:@"OK"], @"");
            XCTAssertTrue( ... , @"");
            return nil;
        }, ^id(NSError* error) {
            // this may fail either due to a timeout or when saveUser fails:
            XCTFail(@"Method failed with error: %@", error);
            return nil;
        }) runLoopWait];  // suspend the run loop, until after the promise gets resolved 
    
    }
    

    A few notes:

    You can execute the success or failure handler (which are registered for the promise with the thenOn statement) on any queue, just specify the queue. This does not dead lock the main thread, even though the handler gets explicitly executed on the main thread, and the test runs as well on the main thread (thanks to the run loop mechanism).

    The method runLoopWait will enter a run loop, and only return once the promise has been resolved. This is both, effective and efficient.

    A promise accepts a timeout. If the timeout expires, the promise will be "rejected" (that is resolved) with a corresponding error.

    IMO, promises are an invaluable tool for handling common asynchronous programming problems - not just a helper for unit tests. (See also: wiki article Futures and promises.

    Please note, I'm the author of the RXPromise library, and thus I'm totally biased ;)

    There are other Promise implementations for Objective-C as well.

提交回复
热议问题