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.
- Getting started with OCMock
- Setting up OCMock for iOS development
- What's new in OCMock 3
- OCMock 2 features page
- Creating mock objects
- Stubbing methods
- Verifying interactions
- Argument constraints
- Mocking class methods
- Partial mocks
- Strict mocks and expectations
- Observer mocks
- Advanced topics
Creating mock objects
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.
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
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.
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.
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 that return objects
Tells the mock object that when
someMethod is called it should return
Stubbing methods that return values
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
Delegating to another method
In this case the mock object will call
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
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
The mock object will set the reference that is passed to the method to
setTo: for pass-by-reference arguments that return objects and
OCMOCK_VALUE() for arguments that return primitives.
Invoking block arguments
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.
someMethod is invoked the stub will throw
someMethod is invoked the stub will post
Chaining stub actions
All actions such as
andPost can be chained. In this example the mock object will post a notification and return the value.
Forwarding to the real object / class
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.
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.
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
It is possible to stub a method and still verify that it has been called.
The any constraint
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
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
NOTE: this should have a modern syntax.
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.
checkWithSelector:onObject:, when the mock object receives
someMethod:, it invokes
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
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
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
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
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
Restoring the class
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
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.
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
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
Strict mocks and expectations
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
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
It is possible to use
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
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
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.
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.
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
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:
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
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
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.
IMPORTANT: 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.
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.
Only one mock at a time can stub class methods on a given class
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
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
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
It is not possible to mock a number of core runtime methods. This includes
respondsToSelector:, and several others.
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
It is not possible to stub or verify class methods on
NSArray. Trying to do so has no effect.
Methods on NSObject cannot be verified
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
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.
The test cases in OCMockTests show all uses and most edge cases.
Changes.txt contains a chronological list of all changes.