blob: 2f730ed36727b746be3b22df6d08fcf259f48e1e [file] [log] [blame] [edit]
---
layout: default
title: What's new in OCMock 3
tags: []
status: publish
type: page
published: true
comments: false
---
<h1>{{ page.title }}</h1>
<p>OCMock 3 is almost completely backwards compatible with previous versions of OCMock while introducing the following changes:
<ol>
<li>Modern syntax
<li>Verify after running
<li>Apache 2 license
</ol>
<p>This page describes the changes. For a description of all the features please consult the <a href="{{ site.baseurl }}/reference">reference page</a>.
<h2 class="toc numbered">Modern syntax</h2>
<p>In addition to the existing syntax OCMock 3 introduces a new &ldquo;modern&rdquo; syntax that uses macros and round brackets. We believe that there are several benefits:
<ul>
<li>Better error reporting: failures are reported with location in Xcode/AppCode
<li>Blends in with other testing frameworks: XCT and other frameworks also use a function-like syntax
<li>Clearer distinction between mock setup and method calls
</ul>
<p>Examples of the new syntax:
{% highlight objc %}
id mock = OCMClassMock([NSString class]);
OCMStub([mock uppercaseString]).andReturn(@"TEST_STRING");
id partial = OCMPartialMock(anObject);
OCMExpect([partial exampleMethod]).andForwardToRealObject().andReturn(@"TEST_STRING");
{% endhighlight objc %}
<p>These are equivalent to the following code in OCMock 2:
{% highlight objc %}
id mock = [OCMockObject niceMockForClass:[NSString class]];
[[[mock stub] andReturn:@"TEST_STRING"] uppercaseString];
id partial = [OCMockObject partialMockForObject:anObject];
[[[[partial expect] andForwardToRealObject] andReturn:@"TEST_STRING"] exampleMethod];
{% endhighlight objc %}
<p>The following &ldquo;functions&rdquo; are available. (They are not implemented as C functions.)
<p>Creating mock objects:
<ul>
<li><b>OCMClassMock(cls)</b>: creates a new nice class mock object
<li><b>OCMStrictClassMock(cls)</b>: creates a class mock object
<li><b>OCMProtocolMock(protocol)</b>: creates a nice protocol mock object
<li><b>OCMStrictProtocolMock(protocol)</b>: creates a protocol mock object
<li><b>OCMPartialMock(obj)</b>: creates a partial mock for the object
<li><b>OCMObserverMock()</b>: creates an observer mock object
</ul>
<p>Creating stubs and expectations:
<ul>
<li><b>OCMStub(invocation)</b>: creates a stub for a class or instance method invocation
<li><b>OCMExpect(invocation)</b>: creates an expectation for a class or instance method invocation
<li><b>OCMStub(ClassMethod(invocation))</b>: creates a stub for the class method invocation
<li><b>OCMExpect(ClassMethod(invocation))</b>: creates an expectation for the class method invocation
</ul>
<p>The use of <code>ClassMethod</code> 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.
<p>Setting up stubs and expectations:
<ul>
<li><b>andReturn(something)</b>: tells a stub/expecation to return an object or a value
<li><b>andPost(aNotification)</b>: posts a notification
<li><b>andThrow(anException)</b>: throws an exception
<li><b>andCall(anObject, aSelector)</b>: calls a selector on an object
<li><b>andDo(aBlock)</b>: calls a block
<li><b>andForwardToRealObject()</b>: forwards method to real object (partial mocks and class methods)
</ul>
<p>Verification:
<ul>
<li><b>OCMVerifyAll(mock)</b>: verifies all expectations on the mock
<li><b>OCMVerifyAllWithDelay(mock, delay)</b>: verifies all expectations on the mock, waiting for the expectations
</ul>
<p>It is possible to mix and match the new syntax with the traditional method-based syntax.
<h2 class="numbered">Verify after running</h2>
<p>Most of the original mock frameworks follow the <i>expect-run-verify</i> 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 <a href="https://github.com/mockito/mockito">Mockito</a> framework pioneered a new approach: <i>verify-after-running</i>. There are no expectations, all mocks are <i>nice</i>, 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.
<p>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 <b>verify</b> method and the <b>OCMVerify</b> function allow verification after the fact:
{% highlight objc %}
id mock = OCMClassMock([NSString class]);
/* code under test, do something with the mock */
OCMVerify([mock uppercaseString]);
id mock = [OCMockObject niceMockForClass:[NSString class]];
/* code under test, do something with the mock */
[[mock verify] uppercaseString];
{% endhighlight objc %}
<p>In this example, the code under test can call any methods on the mock object. No checking is done. Only when <b>OCMVerify()</b> or the <b>verify</b> method are called, the mock verifies whether the respective invocation has occured and, if not, reports an error.
<h2 class="numbered">Apache 2 license</h2>
<p>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.