blob: 1251ca83640183a38876a8d8b891942c8eb9e72e [file] [edit]
---
layout: minimal
---
<section id="welcome" class="group">
<div id="welcomebox">
<img id="logo" src="{{ site.baseurl }}/images/ocmock-504x162.png" width="252" height="81" alt="OCMock"><br>
<div id="welcomebox-text">
<ul>
<li><b>Mock objects for Objective-C</b>
<li>Stubs &ndash; return values for specific method invocations
<li>Dynamic Mocks &ndash; verify interaction patterns
<li>Partial Mocks &ndash; overwrite methods of existing objects
</ul>
</div>
<div id="welcomebox-buttons">
<a href="{{ site.baseurl }}/download" class="button"><span class="welcomebox-btn-main">Download</span></a>
</div>
</div>
</section>
<section id="content" class="group">
<div id="contentbox">
<h2>Adding OCMock to your project</h2>
<ul>
<li>Download a release from the <a href="{{ site.baseurl }}/download">downloads page</a>.
<li>For iOS development add the static library</a> to your test target. This is described in detail on the <a href="{{ site.baseurl }}/ios">iOS page</a>.
<li>For OS X development simply add <code>OCMock.framework</code> to your test target.
<li>Alternatively you can use Carthage or CocoaPods.
<li>Add an import to your unit tests.
</ul>
{% highlight objc %}
#import <OCMock/OCMock.h>
{% endhighlight objc %}
<h2>Using OCMock &ndash; the short version</h2>
<h3>Creating stubs for instance and class methods</h3>
<p>A mock object stands in for a real object. With stubs we can specify what to return when a method is invoked:
{% highlight objc %}
// create a mock for the user defaults
id userDefaultsMock = OCMClassMock([NSUserDefaults class]);
// set it up to return a specific value when stringForKey: is called
OCMStub([userDefaultsMock stringForKey:@"MyAppURLKey"]).andReturn(@"http://testurl");
// set it up to return the specified value no matter how the method is invoked
OCMStub([userDefaultsMock stringForKey:[OCMArg any]]).andReturn(@"http://testurl");
{% endhighlight objc %}
<p>How do we get the code that we want to test to use the mock? A pattern that is often implemented together with mocks is <a href="http://en.wikipedia.org/wiki/Dependency_injection">dependency injection</a>. With cases like <code>NSUserDefaults</code> we can take an even simpler approach. Our code under test is likely to use the standard shared instance, which is returned by the <code>standardUserDefaults</code> factory class method. We can simply stub that class method:
{% highlight objc %}
// stub a class method to return our mock, and not the standard shared instance
OCMStub([userDefaultsMock standardUserDefaults]).andReturn(userDefaultsMock);
{% endhighlight objc %}
<p>Class methods can be stubbed like instance methods. If a class has a class method and an instance method with the same name, OCMock provides a way to specify which one to target. This is described on the <a href="{{ site.baseurl }}/reference#mocking-class-methods">reference page</a>.
<h3>Verifying behaviour with a mock</h3>
<p>Sometimes we not only want to stub a method but we want to ensure (verify) that a given method has been called by the code under test.
{% highlight objc %}
// create a mock for the user defaults and make sure it's used
id userDefaultsMock = OCMClassMock([NSUserDefaults class]);
OCMStub([userDefaultsMock standardUserDefaults]).andReturn(userDefaultsMock);
// call the code under test
[myController updateUserDefaults];
// verify it has called the expected method
OCMVerify([userDefaultsMock setObject:@"http://someurl" forKey:@"MyAppURLKey"]);
{% endhighlight objc %}
<p>When verifying method invocations matchers can be used for the arguments in the same way as described above.
<h3>Mocking methods on an existing object: partial mocks</h3>
<p>Sometimes we only want to stub or verify a couple of methods, but use the real implementation for all other methods. This is where partial mocks come in:
{% highlight objc %}
// create an object and a partial mock for it
Foo *myObject = [[Foo alloc] init];
id myObjectMock = OCMPartialMock(myObject);
// replace (stub) one method on the object
OCMStub([myObjectMock writeToDatabase]).andReturn(@YES);
// call the code under test
[myController updateDatabase]
// verify that the method has been called
OCMVerify([myObjectMock writeToDatabase]);
{% endhighlight objc %}
<p>It is not even necessary to stub a method in order to verify it. If we omit the stub from the code above the actual implementation of <code>writeToDatabase</code> in the object is used. We can still verify that it has been called.
<h2>Further reading</h2>
<p>With the examples on this page we've barely scratched the surface. OCMock has a rich feature set for many different use cases. The following pages provide good next steps to continue learning about OCMock.
<ul>
<li><a href="{{ site.baseurl }}/introduction">Getting started with OCMock</a>
<li><a href="{{ site.baseurl }}/reference">Reference documentation</a>
<li><a href="{{ site.baseurl }}/support">Tutorials</a> written by OCMock users
<li><a href="http://martinfowler.com/articles/mocksArentStubs.html">Mocks aren't stubs</a>, an article by Martin Fowler
</ul>
<h2>Need help?</h2>
<p>Please ask questions on StackOverflow with the <a href="http://stackoverflow.com/questions/tagged/ocmock"><span class="tag">ocmock</span></a> tag.
</div>
</section>