Reputation: 9742
I just upgraded to XCode 7 recently, forcing me to upgrade OCMock so that I have support for x64 architectures. Apparently a change was made in OCMock which does not allow for a previously mocked object to be remocked-- in other words, I had a helper method that did something like this:
-(MyObject *)getObject {
Factory *factory = [self.dependencyInjector getInstance:factory];
id mockFactory = [OCMockObject partialMockForObject:factory];
[[[mockFactory stub] andReturn:@"important-value"] thing];
return [[MYObject alloc] initWithFactory:mockFactory];
}
This worked fine previously, but apparently there was a change to OCMockObject to not allow a re-mocking of an already mocked object. Since the factory object returned by the injector is effectively a singleton, subsequent calls to the getObject method is calling partialMockForObject: on it multiple times and this now throws an exception "Another mock is already associated with object".
Is there any way to make OCMock not throw an error? I tried calling stopMocking on the object prior to mocking it, but that does not fix this issue. The only way around it was to do something like:
-(MyObject *)getObject {
if (!self.mockFactory) {
Factory *factory = [self.dependencyInjector getInstance:factory];
id mockFactory = [OCMockObject partialMockForObject:factory];
[[[mockFactory stub] andReturn:@"important-value"] thing];
self.mockFactory = mockFactory;
}
return [[MYObject alloc] initWithFactory:self.mockFactory];
}
which is really annoying to have to do...
Upvotes: 0
Views: 1322
Reputation: 315
I ran into this issue and it turned out to be a race condition.
The mock was instantiated using a common factory that was injected into a class under test. The class under test performed some action and then called the factory to create the mock object on a global queue without any consistent thread specified.
The solution I went with was to create a static instance of the mocked object and reuse it throughout my tests.
Upvotes: 0
Reputation: 3014
Looking at the code as it is today, the implementation of stopMocking
explicitly resets the associated object (https://github.com/erikdoe/ocmock/blob/dd5599695dcc50afe4d6bdff509ed3cbe389c667/Source/OCMock/OCPartialMockObject.m#L80). I'm at a loss how calling stopMocking
doesn't solve the problem. Can you build a debug version of OCMock and set a breakpoint at the line highlighted above and see whether it's called?
Upvotes: 1