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
- Getting started with OCMock
- Setting up OCMock for iOS development
- What's new in OCMock 3
- OCMock 2 features page
Contents
- Creating mock objects
- Stubbing methods
- Verifying interactions
- Argument constraints
- Mocking class methods
- Partial mocks
- Strict mocks and expectations
- Observer mocks
- Advanced topics
- Limitations
Creating mock objects
Class mocks
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
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.
Partial mocks
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 it is invoked using a reference to the real object, the mock will still be able to handle the invocation, which means that the stubbed method will be used and it is possible to verify that the method has been invoked.
There are some subtleties when using partial mocks. See partial mocks below.
Observer mocks deprecated
Observer mocks are deprecated as of OCMock 3.8. Please use XCTNSNotificationExpectation instead.
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
Tells the mock object that when someMethod
is called it should return anObject
.
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 int
).
Delegating to another method
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
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.
IMPORTANT: If you read the arguments from the invocation and get hard-to-explain crashes, please read the answer to this question on StackOverflow.
Returning values in pass-by-reference arguments
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
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
When someMethod
is invoked the stub will throw anException
.
Posting notifications
When someMethod
is invoked the stub will post aNotification
.
Chaining stub actions
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
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
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.
Fulfilling XCTest expectations requires OCMock 3.8
When the method is invoked an expectation in the XCTest framework is fulfilled. See this test for details.
Logging messages requires OCMock 3.8
When the method is invoked the message constructed from format
and the arguments is logged via NSLog
. It is likely that you want to use this in a chain, maybe followed by andReturn()
or andForwardToRealObject()
.
Breaking into the debugger requires OCMock 3.8
When the method is invoked the debugger is opened as if a breakpoint was hit. The stack will end somewhere in the implementation of OCMock but if you look further up, past the __forwarding__
frames, you should be able to see where your code invoked the method.
Verifying interactions
Verify-after-running
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
It is possible to stub a method and still verify that it has been called.
Quantifiers requires OCMock 3.6
By default, verification simply checks whether a method has been called or, more precisely, whether it has been called at least once. Sometimes tests require to be more specific. Here the test verifies that the doStuff
method was called at least twice.
A number of different quantifiers exist for various cases. The never()
quantifier is simply an abbreviation of times(0)
.
If these macros cause problems in your code, it is possible to define the OCM_DISABLE_SHORT_SYNTAX
or OCM_DISABLE_SHORT_QSYNTAX
preprocessor macros, and use a prefixed form of the macro. In that case times(n)
becomes OCMTimes(n)
and so on. See section 9.6 below for details.
Because it isn't documented anywhere else: for fans of the old, selector-based syntax quantifiers are also available as shown above.
Argument constraints
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 requires OCMock 3.5
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
.
Matching arguments
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
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 ClassMethod()
.
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 stopMocking
.
Partial mocks
Stubbing methods
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
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 stopMocking
.
Strict mocks and expectations
Expect-run-verify
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 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
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.
Observer mocks deprecated
Observer mocks are deprecated as of OCMock 3.8. Please use XCTNSNotificationExpectation instead.
Setup
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
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 requires OCMock 3.3
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 alloc
, new
, copy
, or mutableCopy
.
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. However, when the init
method is called again a after the original initialisation the mock object simply returns self
. This makes it possible to effectively stub an alloc
/init
sequence.
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.
Breaking retain cycles
In order to verify method invocations after runnning, a mock object records all method invocations and, as a side effect, it retains the arguments of the invocations. Now, if the mock itself is an argument or the return value of an invocation that would result in an obvious retain cycle. In these cases the mock does not retain itself.
However, it is possible that an object that is passed as an argument holds a reference to the mock. If the mock retains the argument that object might in turn retain the mock, forming a retain cycle. There really isn't much OCMock can do, other than offer a method to manually break such cycles.
When stopMocking
is called on a mock object, it immediatly clears its list of recorded invocations, which causes the arguments to be released and, as a consequence, retain cycles are broken. If an attempt is made to verify or record invocations after stopMocking
has been called the mock object will throw a descriptive exception.
Disabling short syntax
In a number of places OCMock uses macros that are not prefixed with OCM
, e.g. ClassMethod()
and atLeast()
. This may lead to clashes with macros defined in other libraries. All macros in OCMock have a longer form, too, e.g. OCMClassMethod()
and OCMAtLeast()
.
Defining the preprocessor macro OCM_DISABLE_SHORT_SYNTAX
will supress the definition of the short macros. Defining OCM_DISABLE_SHORT_QSYNTAX
will only skip the new macros introduced for quantifiers in OCMock 3.6.
Stopping creation of mocks for specific classes requires OCMock 3.8
Some frameworks dynamically alter the classes of objects at runtime. OMock does this to implement partial mocks, and the Foundation framework changes classes as part of the the Key-Value Observing (KVO) mechanism. When this is not carefully coordinated unexpected behaviour and or crashes may result. OCMock is aware of KVO and carefully avoids conflicts with it. For other frameworks OCMock only offers a mechanism to opt out of mocking in order to avoid unexpected behaviour.
By implementing the class method shown above a class can opt out of being mocked. When a developer tries to create a mock for such a class an exception will be raised, explaing the problem. It is acceptable that the method returns a different value on separate invocations. This allows it to react to specifc conditions at runtime. The contents of reason
are ignored if the method returns YES
.
For all classes that do not implement this method OCMock assumes that mocking is acceptable.
Checking for partial mock requires OCMock 3.8
In specific cases it might be neccessary to determine whether a partial mock has been created for a given object. This should not be needed in regular tests but it might be neccessary to know for other frameworks that are aware of OCMock.
As described above in partial mocks OCMock dynamically creates a subclass for each partial mock. It sets the class of the object to that subclass but overrides the class
method to return the original class. Using the Objective-C runtime function objc_getClass()
it is possible to get hold of the actual class of an object, which might be a dynamically created subclass for a partial mock. The function OCMIsSubclassOfMockClass()
returns YES
if the class passed as an argument is such a class or a subclass of one.
Limitations
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 init
, class
, methodSignatureForSelector:
, forwardInvocation:
, respondsToSelector:
, and several others.
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
It is not possible to stub or verify class methods on NSString
and NSArray
. Trying to do so has no effect.
Class methods on NSManagedObject and subclasses of it cannot be stubbed or verified
It is not possible to stub or verify class methods on NSManagedObject
or subclasses of it. 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 and #328 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.