|
|
|
|
OCMock is an Objective-C implementation of mock objects. If you are unfamiliar with the concept of mock objects please visit mockobjects.com which has more details and discussions about this approach to testing software. This implementation fully utilises the dynamic nature of Objective-C. It creates mock objects on the fly and uses the trampoline pattern so that you can define expectations and stubs using the same syntax that you use to call methods. No strings, no @selector, just method invocations like this: [[myMockObject expect] doSomethingWithObject:someObject];
If you have any questions please use the new OCMock forum on this site. For contributions and discussions of future development of OCMock please join the mailing list by sending an empty message to ocmock-subscribe@mulle-kybernetik.com. You can also contact me at Erik Doernenburg <erik@mulle-kybernetik.com>. OCMock can be used for iPhone development. Setting up an iPhone project with frameworks can be tricky but the steps involved are explained really well in Colin Barrett's tutorial. 16-Oct-2009New release (1.55) offering several new features, including partial mocks, method swizzling, posting of notifications, and verification of call sequence, as well as a handful of bug fixes. Details in the "Features" tab on this page and in the change notes. 10-Oct-2009The mailing list is great for submitting patches and discussing future development of OCMock. To just get a quick answer for a problem using OCMock it might be a bit too involved, which is why we're going to trial the use of a web-based forum. Have a look at the brand new OCMock Forum. 19-May-2009New release (1.42) which combines several contributions, adding support for mock observers of notifications, setters for pass-by-reference arguments, and several improvements to existing features. The default binary release now uses @rpath, which allows for more flexible deployment, and it supports garbage collection. 07-Jul-2008With this new release (1.29) OCMock supports hamcrest matchers like this: [[mock expect] doSomething:startsWith(@"foo")]
Note that this dependency is optional. OCMock does not require or link against hamcrest, but if the test suite uses hamcrest matchers and links against hamcrest then OCMock works with the matchers. This release also contains a small bugfix that removes a memory leak in OCMockRecorder. 08-May-2008New release (1.24) which combines several contributions, adds support for more flexible constraints as well as experimental 64-bit support. The default binary release is now in “embedded” mode. 22-Nov-2007We now have a mailing list for OCMock. Please send an empty message to ocmock-subscribe@mulle-kybernetik.com to subscribe. The actual mailing list address is ocmock@mulle-kybernetik.com but you must be subscribed to be able to post. (Too much hassle with spam otherwise.) 21-Jun-2007New release (1.17) which combines several contributions. Added nice mocks, which ignore unexpected invocations, and exceptions meant to cause the test to fail fast are now rethrown in verify. 11-Jun-2006New release (1.12) which combines several contributions. Added support for stubbing primitive return types, matching nil and struct arguments, and throwing exceptions. 03-Oct-2005New release (1.10) which has support for mocking protocols. Also added XCode 2.1 compliant project files and moved to built-in OCUnit. 26-Sep-2004Changed a small but important detail: The MockObject and MockRecorder classes now inherit from NSProxy which carries much less baggage in terms of methods that cannot be mocked because they are defined by the base class. 30-Aug-2004First public release. I am using the Subversion revision numbers to version the releases, which is why we start with 1.4 and not 1.0 as one could expect. 23-Jul-2004While working on a new Objective-C project, a Mac OS X monitor for Damage Control, I decide that I've gotten so used to developing test-first and using mock objects that I will bite the bullet and do a simple mock objects implementation in Objective-C. It'll be basic but since Objective-C is so dynamic I probably only need a fraction of the code needed for the Java and .NET versions. Stable Releases
Source codeYou can fetch the latest version of the code from the Subversion repository at
http://svn.mulle-kybernetik.com/OCMock/trunk
LicenseCopyright (c) 2004 - 2009 by Mulle Kybernetik. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation is hereby granted, provided that both the copyright notice and this permission notice appear in all copies of the software, derivative works or modified versions, and any portions thereof, and that both notices appear in supporting documentation, and that credit is given to Mulle Kybernetik in all documents and publicity pertaining to direct or indirect use of this code or its derivatives. THIS IS EXPERIMENTAL SOFTWARE AND IT IS KNOWN TO HAVE BUGS, SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. THE COPYRIGHT HOLDER ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. THE COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF ANY DERIVATIVE WORK. Class mocks
Creates a mock object that can be used as if it were an instance of SomeClass. Expectations and verification
Tells the mock object that someMethod: should be called with an argument that is equal to someArgument. After this setup the functionality under test should be invoked followed by
The verify method will raise an exception if the expected method has not been invoked. Stubs
Tells the mock object that when someMethod: is called with someArgument it should return aValue. If the method returns a primitive type the return value must be wrapped as follows:
Values can also be returned in pass-by-reference arguments:
In this case the mock object will set the reference that is passed to the method to aValue, which currently has to be an object. The mock object can also throw an exception or post a notification when a method is called:
In fact, the notification can be posted in addition to returning a value:
Finally, the mock can delegate the handling of an invocation to a completely different method:
In this case the mock object will call aMethod: on anObject 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. Note that it is possible to use andReturn:, andThrow:, etc with expect, too. This will then return the given return value and, on verify, ensure that the method has been called. Argument constraints
Tells the mock object that someMethod: should be called and it does not matter what the argument is. Pointers require special treatment:
Other constraints available are:
The last constraint will, when the mock object receives someMethod:, send aSelector to anObject and if aSelector takes an argument will pass the argument that was passed to someMethod:. The method should return a boolean indicating whether the argument matched the expectation or not. It is also possible to use Hamcrest matchers like this:
Note that this will only work when the Hamcrest framework is explicitly linked by the unit test bundle. Nice mocks / failing fastWhen a method is called on a mock object that has not been set up with either expect or stub the mock object will raise an exception. This fail-fast mode can be turned off by creating a "nice" mock:
Note that in fail-fast mode, if the exception is ignored, it will be rethrown when verify is called. This makes it possible to ensure that unwanted invocations from notifications etc. can be detected. Protocol mocks
Creates a mock object that can be used as if it were an instance of an object that implements SomeProtocol. Partial mocks
Creates a mock object that can be used in the same way as anObject. When a method that is not stubbed is invoked it will be forwarded anObject. When a stubbed method is invoked using a reference to anObject, rather than the mock, it will still be handled by the mock. Note that currently partial mocks cannot be created for instances of toll-free bridged classes, e.g. NSString. Observer mocks
Creates a mock object that can be used to observe notifications. The mock must be registered in order to receive notifications:
Expectations can then be set up as follows:
Note that currently there is no "nice" mode for observer mocks, they will always raise an exception when an unexpected notification is received. Instance-based method swizzlingIn a nutshell, Method Swizzling describes the replacement of a method implementation with a different implementation at runtime. Using partial mocks and the andCall: stub 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. More detailThe test cases in OCMockObjectTests and OCMockObjectHamcrestTests show all uses of OCMock. Changes.txt contains a chronological list of all changes. Poking Objective-C with a Testing StickGeneral tutorial that explains in detail how to set up a project for testing with OCUnit and OCMock. Also shows how partial mocks can be used to substitute individual methods in a test. OCMock and the iPhoneThis tutorial shows how to set up OCMock for an iPhone project. The project runs the tests on the Mac because OCMock is a framework and frameworks are not supported on the actual iPhone itself. Testing Cocoa ControllersA tutorial that shows how to test Cocoa controller objects without having to load the user interface from the NIB file. The objects defined in InterfaceBuilder are replaced with mocks. Writing custom constraintsOCMock integrates with Hamcrest but sometimes it can be easier to write a constraint using the API used by OCMock's built-in constraints. This tutorial shows how it's done. Applies to iPhone and Cocoa development. Mocking a database connectionThis tutorial describes a classic use case for mock objects, it shows how to replace a dependency on an external call with a mock object that returns canned values. This tutorial is in German. |