OCMock 3 reference

This page describes the features present in OCMock 3.x, using the modern syntax. Previous versions of OCMock used a selector-based syntax. This is still available in OCMock 3, however, the default is the modern syntax.

Related pages

Contents

  1. Creating mock objects
  2. Stubbing methods
  3. Verifying interactions
  4. Argument constraints
  5. Mocking class methods
  6. Partial mocks
  7. Strict mocks and expectations
  8. Observer mocks
  9. Advanced topics
  10. Limitations

Creating mock objects

Class mocks

id classMock = OCMClassMock([SomeClass class]);

Creates a mock object that can be used as if it were an instance of SomeClass. It is possible to mock instance and class methods defined in the class and its superclasses.

There are some subtleties when mocking class methods. See mocking class methods below.

Protocol mocks

id protocolMock = OCMProtocolMock(@protocol(SomeProtocol));

Creates a mock object that can be used as if it were an instance of an object that implements SomeProtocol. Otherwise they work like class mocks.

Strict class and protocol mocks

id classMock = OCMStrictClassMock([SomeClass class]);
id protocolMock = OCMStrictProtocolMock(@protocol(SomeProtocol));

Creates a mock object in strict mode. By default mocks are nice, they return nil (or the correct default value for the return type) for whatever method is called. In contrast, strict mocks raise an exception when they receive a method that was not explicitly expected. See strict mocks and expectations below.

Partial mocks

id partialMock = OCMPartialMock(anObject);

Creates a mock object that can be used in the same way as anObject. Any method that is not stubbed is forwarded to anObject. When a method is stubbed and that method is invoked using a reference to the real object, the mock will still be able to handle the invocation. Similarly, when a method is invoked using a reference to anObject, rather than the mock, it can still be verified later.

There are some subtleties when using partial mocks. See partial mocks below.

Observer mocks

id observerMock = OCMObserverMock();

Creates a mock object that can be used to observe notifications. The mock must be registered in order to receive notifications. See observer mocks below for details.

Stubbing methods

Stubbing methods that return objects

OCMStub([mock someMethod]).andReturn(anObject);

Tells the mock object that when someMethod is called it should return anObject.

Stubbing methods that return values

OCMStub([mock aMethodReturningABoolean]).andReturn(YES);

For methods that return primitive values it is important to use the right type of value. If, for example, a method returns a long but the stub uses an int an error will occur. The message will include the expected and the actual type (using Objective-C type codes such as “q” for long and “i” for int).

Delegating to another method

OCMStub([mock someMethod]).andCall(anotherObject, @selector(aDifferentMethod));

In this case the mock object will call aDifferentMethod on anotherObject when someMethod is called. The signature of the replacement method must be the same as that of the method that is replaced. Arguments will be passed, and the return value of the replacement method is returned from the stubbed method. It is common to implement the replacement method in the test case itself.

Delegating to a block

OCMStub([mock someMethod]).andDo(^(NSInvocation *invocation)
    { /* block that handles the method invocation */ });

The mock object will call the passed block when someMethod is called. The block can read the arguments from the invocation object, and it can use the invocation object to set up a possible return value.

Returning values in pass-by-reference arguments

OCMStub([mock someMethodWithReferenceArgument:[OCMArg setTo:anObject]]);
OCMStub([mock someMethodWithReferenceArgument:[OCMArg setToValue:OCMOCK_VALUE((int){aValue})]]);

The mock object will set the reference that is passed to the method to anObject and aValue. Use setTo: for pass-by-reference arguments that return objects and setToValue: and OCMOCK_VALUE() for arguments that return primitives.

Invoking block arguments

OCMStub([mock someMethodWithBlock:[OCMArg invokeBlock]]);
OCMStub([mock someMethodWithBlock:([OCMArg invokeBlockWithArgs:@"First arg", nil])]);

The mock object will invoke the block passed as an argument to the stubbed method. If the block takes arguments and invokeBlock is used, the default values for the argument types are used, e.g. zero for a numerical type. Using invokeBlockWithArgs: it is possible to specify which arguments to invoke the block with; non-object arguments must be wrapped in value objects and the expression must be wrapped in round brackets.

Throwing exceptions

OCMStub([mock someMethod]).andThrow(anException);

When someMethod is invoked the stub will throw anException.

Posting notifications

OCMStub([mock someMethod]).andPost(aNotification);

When someMethod is invoked the stub will post aNotification.

Chaining stub actions

OCMStub([mock someMethod]).andPost(aNotification).andReturn(aValue);

All actions such as andReturn and andPost can be chained. In this example the mock object will post a notification and return the value.

Forwarding to the real object / class

OCMStub([mock someMethod]).andForwardToRealObject();

When using a partial mock and when mocking class methods it is possible to stub a method and forward it to the real object (in case of partial mocks) or to the class (when mocking class methods). This is only useful when chaining actions or when using expectations.

Doing nothing

OCMStub([mock someMethod]).andDo(nil);

It is possible to pass nil instead of a block to andDo. This is only useful with partial mocks or when mocking class methods. In these cases using andDo(nil) effectively suppresses the behaviour in the existing class.

Verifying interactions

Verify-after-running

id mock = OCMClassMock([SomeClass class]);

/* run code under test */

OCMVerify([mock someMethod]);

Verifies that someMethod has been called by the code under test. If the method has not been invoked an error is reported. In Xcode and AppCode the error is reported on the line of the verify, for other test environments an exception is thrown.

It is possible to use argument constraints in the verify statement.

Stubs and verification

id mock = OCMClassMock([SomeClass class]);
OCMStub([mock someMethod]).andReturn(myValue);

/* run code under test */

OCMVerify([mock someMethod]);

It is possible to stub a method and still verify that it has been called.

Argument constraints

The any constraint

OCMStub([mock someMethodWithAnArgument:[OCMArg any]])
OCMStub([mock someMethodWithPointerArgument:[OCMArg anyPointer]])
OCMStub([mock someMethodWithSelectorArgument:[OCMArg anySelector]])

Adds a stub for the methods which is active for all invocations, no matter what argument is passed. Pointers and selectors require special treatment as shown above. Arguments that are neither objects nor pointers or selectors cannot be ignored using an any placeholder (for details see this forum thread). See just below for a workaround.

Ignoring non-object arguments

[[[mock stub] ignoringNonObjectArgs] someMethodWithIntArgument:0]

This tells the mock to ignore all non-object arguments in the invocation. It will accept any invocation of someMethodWithIntArgument: no matter what argument is actually passed. If the method has object arguments as well as non-object arguments, the object arguments can still be constrained as usual using the methods on OCMArg.

NOTE: this should have a modern syntax.

Matching arguments

OCMStub([mock someMethod:aValue)
OCMStub([mock someMethod:[OCMArg isNil]])
OCMStub([mock someMethod:[OCMArg isNotNil]])
OCMStub([mock someMethod:[OCMArg isNotEqual:aValue]])
OCMStub([mock someMethod:[OCMArg isKindOfClass:[SomeClass class]]])
OCMStub([mock someMethod:[OCMArg checkWithSelector:aSelector onObject:anObject]])
OCMStub([mock someMethod:[OCMArg checkWithBlock:^BOOL(id value) { /* return YES if value is ok */ }]])

If an argument is passed when the stub is created, the stub only matches invocations with that exact argument. Calls with different arguments are not matched. The OCMArg class provides several methods that allow matching values in different ways.

For checkWithSelector:onObject:, when the mock object receives someMethod:, it invokes aSelector on anObject. If the method takes an argument the mock will pass the argument that was passed to someMethod:. The method should return a boolean indicating whether the argument matched the expectation or not.

Using Hamcrest matchers

OCMStub([mock someMethod:startsWith(@"foo")])

It is also possible to use Hamcrest matchers. This will only work when the Hamcrest framework is explicitly linked by the unit test bundle. OCMock does not declare a dependency on Hamcrest and discovers it using runtime functions.

Mocking class methods

Stubbing class methods

id classMock = OCMClassMock([SomeClass class]);
OCMStub([classMock aClassMethod]).andReturn(@"Test string");

// result is @"Test string"
NSString *result = [SomeClass aClassMethod];

Stubs for class methods are set up exactly like stubs for instance methods. However, behind the scenes the mock object makes some changes to the class. (It dynamically creates a new meta class and makes the class use that instead of its own meta class.) This allows OCMock to stub calls which are made directly to the class.

IMPORTANT: If the mock object that added a stubbed class method is not deallocated then the stubbed method will persist across tests. If multiple mock objects manipulate the same class at the same time the behaviour is undefined.

Verifying invocations of class methods

id classMock = OCMClassMock([SomeClass class]);

/* run code under test */

OCMVerify([classMock aClassMethod]);

Verification is done in the same way as with instance methods. As described above, calls can be made directly to the class.

Disambiguating class and instance methods

id classMock = OCMClassMock([SomeClass class]);
OCMStub(ClassMethod([classMock ambiguousMethod])).andReturn(@"Test string");

// result is @"Test string"
NSString *result = [SomeClass ambiguousMethod];

In cases where a class method should be stubbed but the class also has an instance method with the same name as the class method, as assumed with ambiguousMethod above, the intent to mock the class method must be made explicit using ClassMethod().

Restoring the class

id classMock = OCMClassMock([SomeClass class]);

/* do stuff */

[classMock stopMocking];

The class can be returned to its original state by calling stopMocking. This is only necessary if the original state must be restored before the end of the test. The mock automatically calls stopMocking during its own deallocation.

When the class is returned to its original state, its meta class will be switched back to the original meta class. This effectively removes all the stubs. However, this also makes it impossible for the mock to add new stubs or to verify interactions. You should really not use a mock after having called stopMocking.

Partial mocks

Stubbing methods

id partialMock = OCMPartialMock(anObject);
OCMStub([partialMock someMethod]).andReturn(@"Test string");

// result1 is @"Test string"
NSString *result1 = [partialMock someMethod];

// result2 is @"Test string", too!
NSString *result2 = [anObject someMethod];

From an API perspective stubs on partial mocks are set up in the same way as on class and protocol mocks. Partial mocks alter the class of the mocked object, though. (In fact, they create a subclass and switch the class of the mocked object to that subclass.) This means that calls using a reference to the real object, even including self in methods where the object calls itself, are also affected by stubs and expectations.

Verifying invocations

id partialMock = OCMPartialMock(anObject);

/* run code under test */

OCMVerify([partialMock someMethod]);

Verification is done in the same way as with class and protocol mocks. As described just above, calls using a reference to the real object are intercepted, too. There is no need to insure that a reference to the mock is used, calls can be made using references to the real object.

Restoring the object

id partialMock = OCMPartialMock(anObject);

/* do stuff */

[partialMock stopMocking];

The real object can be returned to its original state by calling stopMocking. This is only necessary if the original state must be restored before the end of the test. The partial mock automatically calls stopMocking during its own deallocation.

When the object is returned to its original state, its class will be switched back to the original class. This effectively removes all the stubs. However, this also makes it impossible for the partial mock to add new stubs or to verify interactions. You should really not use a partial mock after having called stopMocking.

Strict mocks and expectations

Expect-run-verify

id classMock = OCMClassMock([SomeClass class]);
OCMExpect([classMock someMethodWithArgument:[OCMArg isNotNil]]);

/* run code under test, which is assumed to call someMethod */

OCMVerifyAll(classMock)

This is the original approach to mocking. First the mock object is set up with expectations, then the code under test is run, and afterwards the expectations are verified. If an expected method has not been invoked, or has not been invoked with the right arguments, then an error is reported. As shown it is possible to use argument constraints in the expect statement. Strict mocks can be created for classes and protocols.

If in doubt use the newer verify-after-running approach described in Verifying interactions.

Strict mocks and failing fast

id classMock = OCMStrictClassMock([SomeClass class]);
[classMock someMethod]; // this will throw an exception

The mock has been set up as a strict mock without any expectations. Calling someMethod will cause the mock to throw an exception. This is also known as failing fast because the test fails immediatly when the unexpected call is made. Only strict mocks fail fast.

Stub actions and expect

id classMock = OCMStrictClassMock([SomeClass class]);
OCMExpect([classMock someMethod]).andReturn(@"a string for testing");

/* run code under test, which is assumed to call someMethod */

OCMVerifyAll(classMock)

It is possible to use andReturn, andThrow, etc with expectations, too. This will then run the stub action if and when the method is invoked and, on verify, ensure that the method was actually invoked.

Verify with delay

id mock = OCMStrictClassMock([SomeClass class]);
OCMExpect([mock someMethod]);

/* run code under test, which is assumed to call someMethod eventually */

OCMVerifyAllWithDelay(mock, aDelay);

In certain cases the expected method will only be called when the run loop is active. For these cases it is possible to delay the verification for a while. Note that aDelay (expressed as NSTimeInterval) is the maximum the mock will wait. It normally returns as soon as the expectations have been met.

Verifying in order

id mock = OCMStrictClassMock([SomeClass class]);
[mock setExpectationOrderMatters:YES];
OCMExpect([mock someMethod]);
OCMExpect([mock anotherMethod]);

// calling anotherMethod before someMethod will cause an exception to be thrown
[mock anotherMethod];

The mock can be told to verify that expected methods are called in the same order as the expectations are set up. As soon as a method is called that is not next on the “expected list” the mock will fail fast and throw an exception.

Observer mocks

Setup

id observerMock = OCMObserverMock();
[notificatonCenter addMockObserver:aMock name:SomeNotification object:nil];
[[mock expect] notificationWithName:SomeNotification object:[OCMArg any]];

Creates a mock object that can be used to observe notifications, registers it with a notification center, and tells the mock to expect SomeNotification with any object.

Verification

OCMVerifyAll(observerMock);

Currently observer mocks are always strict, they will raise an exception when an unexpected notification is received. This implies that individual notifications cannot be verified after the fact. All notifications must be set up with expect, and they are verified together after the code under test has run using OCMVerifyAll.

Advanced topics

Failing fast for regular (nice) mocks

On a strict mock object, when a method is called that has not been mocked (using some variant of stub or expect) the mock object will raise an exception. It will fail fast. Regular mock objects simply return the default value for the return type. Regular mocks can be configured on a per-method basis to fail fast:

id mock = OCMClassMock([SomeClass class]);
OCMReject([mock someMethod]);

In this case the mock will accept all methods except someMethod; if that is invoked the mock will throw an exception.

Re-throwing fail fast exceptions in verify all

In fail-fast mode an exception might not cause the test to fail. This can happen when the call stack for the method does not end in the test. Fail fast exceptions will be re-thrown when OCMVerifyAll is called. This makes it possible to ensure that unwanted invocations from notifications etc. can be detected.

Stubbing methods that create objects

id classMock = OCMClassMock([SomeClass class]);
OCMStub([classMock copy])).andReturn(myObject);

It is possible to stub class and instance methods that conceptually create objects. OCMock automatically adjusts the reference count of the returned object when stubbing methods that have a name that begins with alloc, new, copy, or mutableCopy.

id classMock = OCMClassMock([SomeClass class]);
OCMStub([classMock new])).andReturn(myObject);

It possible, although not advisable, to stub out new for a class. If you find yourself doing this a lot, please consider the dependency injection pattern. It is not possible to stub the init method, because that is implemented by the mock itself.

Instance-based method swizzling

In a nutshell, Method Swizzling describes the replacement of a method implementation with a different implementation at runtime. Using partial mocks and the andCall action OCMock allows such replacements on a per-instance basis.

id partialMock = OCMPartialMock(anObject);
OCMStub([partialMock someMethod]).andCall(differentObject, @selector(differentMethod));

After these two lines, when someMethod is sent to anObject the implementation of that method is not invoked. Instead, differentMethod is called on differentObject. Other instances of the same class are not affected; for these the original implementation of someMethod is still invoked. The methods can have different names but their signatures should be the same.

Limitations

Only one mock at a time can stub class methods on a given class

// don't do this
id mock1 = OCMClassMock([SomeClass class]);
OCMStub([mock1 aClassMethod]);
id mock2 = OCMClassMock([SomeClass class]);
OCMStub([mock2 anotherClassMethod]);

As mentioned above, if the mock object that added a stubbed class method is not deallocated then the stubbed method will persist, even across tests. If multiple mock objects manipulate the same class at the same time the behaviour is undefined.

Setting up expect after stub on the same method does not work

id mock = OCMStrictClassMock([SomeClass class]);
OCMStub([mock someMethod]).andReturn(@"a string");
OCMExpect([mock someMethod]);

/* run code under test */

OCMVerifyAll(mock); // will complain that someMethod has not been called

The code above first sets up a stub for someMethod and afterwards an expectation for the same method. Due to the way mock objects are currently implemented any calls to someMethod are handled by the stub. This means that even if the method is called the verify fails. It is possible to avoid this problem by adding andReturn to the expect statement. You can also set up a stub after the expect.

Partial mocks cannot be created for certain special classes

id partialMockForString = OCMPartialMock(@"Foo"); // will throw an exception

NSDate *date = [NSDate dateWithTimeIntervalSince1970:0];
id partialMockForDate = OCMPartialMock(date); // will throw on some architectures

It is not possible to create partial mocks for instances of toll-free bridged class, e.g. NSString, or for objects represented with tagged pointers, e.g. NSDate on some architectures. The mock object will throw a descriptive exception should you try to do this.

Certain methods cannot be stubbed or verified

id partialMockForString = OCMPartialMock(anObject);
OCMStub([partialMock class]).andReturn(someOtherClass); // will not work

It is not possible to mock certain core runtime methods including init, class, methodSignatureForSelector:, and forwardInvocation:. Note that class is automatically stubbed to return the original class of the object, and not the dynamic subclass used by the partial mock.

Class methods on NSString and NSArray cannot be stubbed or verified

id stringMock = OCMClassMock([NSString class]);
// the following will not work
OCMStub([stringMock stringWithContentsOfFile:[OCMArg any] encoding:NSUTF8StringEncoding error:[OCMArg setTo:nil]]);

It is not possible to stub or verify class methods on NSString and NSArray. Trying to do so has no effect.

Methods on NSObject cannot be verified

id mock = OCMClassMock([NSObject class]);

/* run code under test, which calls awakeAfterUsingCoder: */

OCMVerify([mock awakeAfterUsingCoder:[OCMArg any]]); // still fails

It is not possible use verify-after-running with methods implemented in NSObject or a category on it. In some cases it is possible to stub the method and then verify it. It is possible to use verify-after-running when the method is overriden in a subclass.

Private methods in core Apple classes cannot be verified

UIWindow *window = /* get window somehow */
id mock = OCMPartialMock(window);

/* run code under test, which causes _sendTouchesForEvent: to be invoked */

OCMVerify([mock _sendTouchesForEvent:[OCMArg any]]); // still fails

It is not possible use verify-after-running with private methods in core Apple classes. Specifically, all methods with an underscore prefix and/or suffix in a class with either NS or UI as prefix. In some cases it is possible to stub the method and then verify it.

Verify-after-running cannot use a delay

It is currently not possible to verify a method with a delay. This is currently only possible using the expect-run-verify approach described below in strict mocks and expectations.

Using multiple threads in tests

OCMock is not fully thread-safe. Up to version 3.2.x OCMock was not thread-aware at all. Any combination of operations on a mock object from multiple threads was likely to cause issues and make the test fail.

As of OCMock 3.3 it is still necessary to invoke all setup and verification operations from a single thread, preferrably the main thread of the test runner. It is possible, though, to use the mock object from multiple threads. The mock object can even be used from a different thread while its setup continues in the main thread. See #235 for details.

More detail

The test cases in OCMockTests show all uses and most edge cases.

Changes.txt contains a chronological list of all changes.