Centurion
Centurion

Reputation: 14314

How to check passed callback is called from tested method when using OCMock?

How to check passed callback block is called from tested method? Here's simplified method I want to test:

- (void)loadModel:(Callback)callback {

  // Data loading part...

  // Callbacks with data. Second param usually passes data, but now it will pas nil for demo
  callback(YES, nil, nil);
}

Here's my unit test where I want to test if callback was called in method loadModel:

- (void)testLoadModelCallbackIsCalled {

  HomeModel *model = [[HomeModel alloc] init];
  id modelMock = OCMPartialMock(model);

  Callback callback = ^(BOOL success, id result, NSError *error){

    XCTAssertTrue(YES, @"Callback not called");
  };

  //[modelMock expect] ...how to expect?];

  [model loadModel:callback];

  //[modelMock verify];
}

The problem is this test will always pass regardless of callback was called on not. Thought to workaround this with proxy block, however then the whole loadModel method is overridden with the proxy block. I just need to verify loadModel actually calls what I pass.

UPDATE Meanwhile I ended in simplified workaround:

- (void)testLoadModelCallbackIsCalled {

  HomeModel *model = [[HomeModel alloc] init];

  // Create flag for checking
  __block BOOL isCalled = NO;

  Callback callback = ^(BOOL success, id result, NSError *error){

    isCalled = YES;
  };

  XCTAssertTrue(isCalled, @"Callback not called");
}

UPDATE2 @jszumski answer was exactly what I was looking for thought the idea behind XCTestExpectation is very similar to using your own isCalled bool flag.

Upvotes: 1

Views: 632

Answers (1)

jszumski
jszumski

Reputation: 7416

Use XCTestExpectation, which is part of the asynchronous testing framework:

- (void)testLoadModelCallbackIsCalled {
    HomeModel *model = [[HomeModel alloc] init];
    id modelMock = OCMPartialMock(model);

    XCTestExpectation *expectation = [self expectationWithDescription:@"Completion called"];
    Callback callback = ^(BOOL success, id result, NSError *error){
        [expectation fulfill];
    };

    [model loadModel:callback];

    [self waitForExpectationsWithTimeout:1 handler:nil];
}

Upvotes: 2

Related Questions