4

I made a subclass of MKMapView. In unit test, I want to know when I invoke a certain method of this subclass, that a corresponding MKMapView method is invoked and the class of the argument. Can I use OCMock to accomplish this?

EDIT:

I accepted the answer, but I want to clarify that my question was on when the super class cannot be directly stand-in in the unit test (obviously so, because that's how inheritance works). And it seems like both OCMock and OCMockito can only be used for objects that are injecting into the class under the test. So basically, I think I need to resort to manually swizzle them.

huggie
  • 17,587
  • 27
  • 82
  • 139

2 Answers2

4

To answer this question, let's spend a little bit of time to look at how OCMock and similar frameworks work:

Mocking frameworks use the Objective-C runtime to proxy or wrap the original class, so that any invocation of a method on that class is redirected to the mocking framework, which has a pre-recorded set of instructions about what to do when a given method is invoked.

Therefore, the answer is, yes, when you mock a class, you are also implicitly mocking the methods on the super class. You can record an expectation that this method will be invoked and verify that this happened. You can also verify the arguments that were supplied.

It is not necessary to know the details in order to effectively use a mocking framework, however if you're interested in exploring some approaches to proxying a class, take a look at the following:

Incidentally, my personal favorite mocking framework is OCMockito

Jasper Blues
  • 28,258
  • 22
  • 102
  • 185
  • @huggie - Indeed. Thankfully we're seeing more frameworks that actually use swizzling to do useful stuff. . . Though, I'm still waiting for a) an AOP framework and b) Something to patch out a hard-wired or static dependency in a more expressive way. – Jasper Blues Nov 03 '13 at 04:07
  • Since you understand so much the internals maybe you can try to implement one. :) – huggie Nov 03 '13 at 04:53
  • I would love to, however my current project is keeping me busy: www.typhoonframework.org, I have plenty of plans for other projects, however realistically there's only so many side projects you can do ;) – Jasper Blues Nov 03 '13 at 04:55
  • With OCMockito I can't figure out how to mock a class though. According to Jon (http://stackoverflow.com/questions/19799393/how-do-i-stub-a-class-method-with-ocmockito), it's just a stand-in. If I doesn't swizzle I don't understand how it would could mock the super class. – huggie Nov 19 '13 at 13:36
  • OCMock can't, either. – huggie Dec 03 '13 at 10:52
  • Since you can't call a superclass method from outside of a subclass (without runtime spelunking) it's not clear how a superclass method would ever get called on a mocked object. I mean, the subclass is mocked, so by definition, it's real methods aren't getting called, so it's superclass methods could never be called. What's the goal here? To mock the superclass to verify the behavior of the subclass? – ipmcc Apr 16 '14 at 14:04
2

I don't think OCMock can accomplish this.

See How to Test Calls to Super (iosunittesting.com)

I found the above linked post to be very helpful with this common issue. What I ended up doing was creating a category on the superclass (only in my testing target) which overrides the method in question and sets some global state that can be inspected by a test case (approach #1 in the post).

tboyce12
  • 1,449
  • 14
  • 28