5

I'm trying to use OCMock to mock out internal class dependencies (e.g. my class uses an NSMutableData and verifying against a mock NSMutableData). Specifically I'm mocking factory methods to return mock objects.

As far as I can tell the mock objects are not cleaning up class method mocks, or only cleaning them up partially. This is having pretty adverse effects on unrelated tests that may end up invoking the same class methods.

A short example I've been able to repro locally to illustrate:

id data1 = [NSMutableData data];    // new instance
id data2 = [NSMutableData data];    // new instance

// mock +data and have it return data1
id mock = [OCMockObject mockForClass:[NSMutableData class]];
[[[[mock stub] classMethod] andReturn:data1] data];

id foo = [NSMutableData data];  // foo == data1 ok that's good

[mock stopMocking];
mock = nil;                     // using ARC so no explicit -release

id bar = [NSMutableData data];  // bar == data1, wait what? shouldn't this be new?

I've found the problem even worse if you mock +new. That last line where I create bar blows up with either a bad string hash or a stack overflow (I'm not sure how to consistently get one or the other, I've seen both).

I realize there's ways around this. I could inject an NSMutableData instance into my class, which feels like overkill since it's not a hard dependency. I could have an instance method on my class that creates NSMutableData and I partially mock my class instead to inject the mock. That's fine but I would really like to know why this particular case doesn't work. Mocking internal dependencies would be quite a bit easier if I could actually stub out the factory methods!

This issue is not limited to anything particular about NS classes (I'm aware of the limitations around mocking NSString for example) as I can repro the above issue with one of my own classes just as easily.

Brandon
  • 113
  • 5
  • 2
    Support for class methods is new and in active development. You should post this to [the support forum](http://www.mulle-kybernetik.com/forum/viewforum.php?f=4) – Christopher Pickslay Jul 24 '13 at 16:16
  • I'm guessing the issue here is that NSData is a toll-free bridge class. Doesn't look like you are doing anything wrong. – Ben Flynn Jul 24 '13 at 17:40
  • @BenFlynn - NSMutableData is just an example. I can repro this with my own arbitrary Foo class as well. – Brandon Jul 24 '13 at 18:31
  • Bummer. Well if you want to roll your own class method stubbing, I detail an approach at length in this question: http://stackoverflow.com/a/16487040/449161 – Ben Flynn Jul 25 '13 at 20:54
  • 1
    I replied on the forum. Unfortunately, though, I can only say that I can't reproduce the problem. Did you try with the latest released version of OCMock? There were some bugs with class method mocking, but it's now considered (reasonably) stable and complete. – Erik Doernenburg Jul 29 '13 at 21:26

0 Answers0