Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use OCMock to verify that an asynchronous method does not get called in Objective C?

I want to verify that a function is not called. The function is executed in an asynchronous block call inside the tested function and therefore OCMReject() does not work.

The way I have tested if async functions are indeed called would be as follows:

id mock = OCMClassMock([SomeClass class]);
OCMExpect([mock methodThatShouoldExecute]);
OCMVerifyAllWithDelay(mock, 1);

How would a test be done to test if a forbidden function is not called? Something like:

VerifyNotCalled([mock methodThatShouoldExecute]);
OCMVerifyAllWithDelay(mock, 1);
like image 405
Bennie Avatar asked Oct 17 '22 22:10

Bennie


1 Answers

I would recommend using an OCMStrictClassMock instead of the OCMClassMock (which gives you a nice mock). A strict mock will instantly fail your test if any method is called on it that you did not stub or expect, which makes your tests a lot more rigorous.

If that's not an option for you, you can do what you described with:

OCMReject([mock methodThatShouoldExecute]);

See the "Failing fast for regular (nice) mocks" section in the OCMock docs.

Now as for waiting for your code which may call the forbidden method, that's another matter. You can't use OCMVerifyAllWithDelay since that returns immediately as soon as all expectations are met, it doesn't wait around a full second to see if illegal calls will be made to it. One option is to put a 1 second wait before verifying the mock each time. Ideally, you could also wait explicitly on your asynchronous task with an XCTestExpectation. Something like:

XCTestExpectation *asyncTaskCompleted = [self expectationWithDescription:@"asyncTask"];
// Enqueued, in an onCompletion block, or whatever call 
//  ... [asyncTaskCompleted fulfill]

[self waitForExpectationsWithTimeout:1 handler:nil]
like image 61
Dave Avatar answered Oct 21 '22 06:10

Dave