iosiphoneunit-testingocmockito

Unit test case for call back methods ios


I have a following method in my app for which I need to write unit test cases.
Can anyone suggest how can I test whether the success block or error block is called.

- (IBAction)loginButtonTapped:(id)sender
{
    void (^SuccessBlock)(id, NSDictionary*) = ^(id response, NSDictionary* headers) {
        [self someMethod];
    };

    void (^ErrorBlock)(id, NSDictionary*, id) = ^(NSError* error, NSDictionary* headers, id response) {
        // some code
    };

    [ServiceClass deleteWebService:@“http://someurl"
                              data:nil
                  withSuccessBlock:SuccessBlock
                    withErrorBlock:ErrorBlock];
}

Solution

  • You have to use expectations, a relatively recently introduced API. They were added to solve exactly the problem you are having right now, verifying callbacks of asynchronous methods are called.

    Note that you can also set a timeout that will affect the result of the test (slow network connections for example can fire false positives, unless you are checking for slow connections of course, although there are much better ways to do that).

    - (void)testThatCallbackIsCalled {
    
        // Given
        XCTestExpectation *expectation = [self expectationWithDescription:@"Expecting Callback"];
    
        // When
        void (^SuccessBlock)(id, NSDictionary*) = ^(id response, NSDictionary* headers) {
    
            // Then
            [self someMethod];
            [expectation fulfill]; // This tells the test that your expectation was fulfilled i.e. the callback was called.
        };
    
        void (^ErrorBlock)(id, NSDictionary*, id) = ^(NSError* error, NSDictionary* headers, id response) {
    
         // some code
    
        };
    
        [ServiceClass deleteWebService:@“http://someurl"
    
                                               data:nil
    
                                   withSuccessBlock:SuccessBlock
    
                                     withErrorBlock:ErrorBlock];
        };
    
        // Here we set the timeout, play around to find what works best for your case to avoid false positives.
        [self waitForExpectationsWithTimeout:2.0 handler:nil];
    
    }