Unit testing

I am trying to write unit tests for an iOS application that uses the Parse framework, and after many experiments, it seems to fail when writing successful unit tests. I found several messages on testing asynchronous code ( Testing an asynchronous call in unit test in iOS ) and testing network calls, but I have not yet found a way to test calls to the Parse server with asynchronous callbacks.

To give an example, can someone tell me how I will test the following line of code:

[PFUser saveUser:userModelMock withBlock:^(BOOL success, NSError *error) {

}];

I use OCMock and the XCTest framework.

Any help would be greatly appreciated.

* EDIT * This is what I have so far, but seems to be failing.

- (void)testSaveUser {
    id userModelMock = [OCMockObject niceMockForClass:[UserModel class]];
    id userControllerMock = [OCMockObject niceMockForClass:[self.userController class]];

    [[userModelMock expect] saveInBackgroundWithBlock:[OCMArg any]];
    [[userControllerMock stub] saveUser:userModelMock withBlock:[OCMArg any]];

    [userModelMock verify];
}
+4
3

, :

#import <XCTest/XCTest.h>
#import <RXPromise/RXPromise.h>
...

@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 

}

:

( thenOn) , . , , ( ).

runLoopWait , . , .

-. , "" ( ) .

IMO, promises - , . (. : wiki article promises.

, RXPromise, ;)

Promise Objective-C.

+4

, . , :

- (void)testSaveUser {
    id userModelMock = [OCMockObject mockForClass:[UserModel class]];
    id userControllerMock = [OCMockObject partialMockForObject:self.userController];

    [[userModelMock expect] saveInBackgroundWithBlock:[OCMArg any]];
    [userControllerMock saveUser:userModelMock withBlock:[OCMArg any]];

    [userModelMock verify];
}
+1

With a macro WAIT_WHILE(<expression>, <time_limit>)at https://github.com/hfossli/AGAsyncTestHelper/ you can write

- (void)testSaveUser
{
    __block BOOL saved = NO;
    [PFUser saveUser:userModelMock withBlock:^(BOOL success, NSError *error) {
        saved = YES;
    }];
    WAIT_WHILE(!saved, 10.0, @"Failed to save user within 10 seconds timeframe);
}
+1
source

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


All Articles