I recently came across a scenario where I needed to make an assertion on an argument passed to an expected method invocation but OCMock did not provide the constraint I needed. I was testing a FileDetailsViewController that pushes a new FileContentsViewController on to the view stack when a button is pressed. I mocked the UINavigationController so that I could add an assertion that pushViewController:animated: is called with the right arguments.
Note that in this example, I some fanciness is required to assign controller.navigationController = navigationController since it is a readonly property in the UIViewController API. I’ll explain what I did in a later post.
The OCMock feature I was missing is the OCMock.isKindOfClass constraint. So I wrote my own.
Following is the header file that declares the isKindOfClass assertion as a static method in an Objective-C category for OCMock. Categories are kind of like Ruby mixins for Objective-C. You can add static or instance methods to an existing class definition. With this approach I can follow the OCMock pattern of providing static factory methods on the OCMock class for the range of constraints available.
This implementation shows both how to write a custom constraint for OCMock and a use of Objective-C categories to provide a nice API for using it.
In many cases, you’ll want to write a custom constraint that is specific to your test scenario and not appropriate to be shared globally in this manner. In this case you’ll probably follow a similar strategy but implemented in your test class instead of mixed in to OCMockConstraint.