5

I am trying to write some Unit Tests to test some custom NSOperations that we are writing. What I'd like to do is create a Mock of the NSOperation and put it on the NSOperationQueue, and then wait for it to finish. I know I can swizzle the methods and not use OCMock at all, but I really don't want to do that. I'd like to use OCMock. The code I'm trying to run is something like the following:

MYOperation *operation = [MYOperation new];
id mockOperation = [OCMockObject partialMockForObject:operation];
[NSOperationQueue *queue = [NSOperationQueue new];
[queue setMaxConcurrentOperationCount:1];
[queue addOperation:mockOperation];

When the unit test gets to this line:

[queue addOperation:mockOperation];

I get a call to a deallocated object exception. Anyone have any suggestions on how I can overcome this?

user1120133
  • 3,244
  • 3
  • 48
  • 90
Nick Cipollina
  • 501
  • 3
  • 13
  • There is a know problem in the Apple runtime that affects OCMock when ARC is enabled. More detail here: http://www.mulle-kybernetik.com/forum/viewtopic.php?f=4&t=252 – Erik Doernenburg May 24 '12 at 14:28

2 Answers2

2

If you're using ARC, operation is probably released right after you create the mock, as it's not accessed again. If you change it to this, it should fix the error:

[queue addOperation:operation];

...which you should be doing anyways--you're testing your object, not the mock.

Christopher Pickslay
  • 17,523
  • 6
  • 79
  • 92
  • The problem with this approach is that if I stub out a method on the mock, does that get executed or does it execute the method on the actual Operation? – Nick Cipollina May 22 '12 at 19:07
  • With partial mocks, if you stub/expect a method, that method will get invoked on the mock instead of the actual object. Partial mocks provide a way to intercept particular messages sent to an object. From the [OCMock docs](http://ocmock.org/#features): `When a stubbed method is invoked using a reference to anObject, rather than the mock, it will still be handled by the mock.` – Christopher Pickslay May 22 '12 at 22:40
0

When using ARC the reference to the object in mockOperation will be set to nil quite aggressively (too aggressively I think) by the Apple runtime. Not all is lost, though. You can set up your stubs and expectations using mockOperation and still pass operation to the addOperation: method; the partial mock works even when you use a reference to the original object.

Erik Doernenburg
  • 2,933
  • 18
  • 21