What's new in OCMock 3
OCMock 3 is almost completely backwards compatible with previous versions of OCMock while introducing the following changes:
- Modern syntax
- Verify after running
- Apache 2 license
This page describes the changes. For a description of all the features please consult the reference page.
In addition to the existing syntax OCMock 3 introduces a new “modern” syntax that uses macros and round brackets. We believe that there are several benefits:
- Better error reporting: failures are reported with location in Xcode/AppCode
- Blends in with other testing frameworks: XCT and other frameworks also use a function-like syntax
- Clearer distinction between mock setup and method calls
Examples of the new syntax:
These are equivalent to the following code in OCMock 2:
The following “functions” are available. (They are not implemented as C functions.)
Creating mock objects:
- OCMClassMock(cls): creates a new nice class mock object
- OCMStrictClassMock(cls): creates a class mock object
- OCMProtocolMock(protocol): creates a nice protocol mock object
- OCMStrictProtocolMock(protocol): creates a protocol mock object
- OCMPartialMock(obj): creates a partial mock for the object
- OCMObserverMock(): creates an observer mock object
Creating stubs and expectations:
- OCMStub(invocation): creates a stub for a class or instance method invocation
- OCMExpect(invocation): creates an expectation for a class or instance method invocation
- OCMStub(ClassMethod(invocation)): creates a stub for the class method invocation
- OCMExpect(ClassMethod(invocation)): creates an expectation for the class method invocation
The use of
ClassMethod is only necessary if a class contains a class and instance method with the same name and the class method is to be mocked. In all other cases OCMock can determine automatically whether a class or instance method is targeted.
Setting up stubs and expectations:
- andReturn(something): tells a stub/expecation to return an object or a value
- andPost(aNotification): posts a notification
- andThrow(anException): throws an exception
- andCall(anObject, aSelector): calls a selector on an object
- andDo(aBlock): calls a block
- andForwardToRealObject(): forwards method to real object (partial mocks and class methods)
- OCMVerifyAll(mock): verifies all expectations on the mock
- OCMVerifyAllWithDelay(mock, delay): verifies all expectations on the mock, waiting for the expectations
It is possible to mix and match the new syntax with the traditional method-based syntax.
Verify after running
Most of the original mock frameworks follow the expect-run-verify approach. OCMock is one of these frameworks. Over the years, as we all gathered more experience, it became clear that this approach has its problems, and the Mockito framework pioneered a new approach: verify-after-running. There are no expectations, all mocks are nice, i.e. they do not complain when an unexpected method is called, and verification of specific calls is done after the code under test is run.
OCMock 3 supports this approach to testing in addition to the traditional approach. With the modern syntax the default is to create nice mocks. On a mock that has no expectations set the verify method and the OCMVerify function allow verification after the fact:
In this example, the code under test can call any methods on the mock object. No checking is done. Only when OCMVerify() or the verify method are called, the mock verifies whether the respective invocation has occured and, if not, reports an error.
Apache 2 license
It has become clear that a non-standard BSD-style license with attribution clause is not ideal. I am not a lawyer but the Apache 2 license seems quite close in spirit to the existing license, and it has the benefit of being a widely used standard open source license. For that reason OCMock 3 has been released under the Apache 2 license. If you are a previous contributor and you have concerns please do get in touch.