erikdoe / ocmock

Mock objects for Objective-C
http://ocmock.org
Apache License 2.0
2.16k stars 606 forks source link

niceMockForClass crash #292

Closed pwillsey closed 8 years ago

pwillsey commented 8 years ago

After updating to OCMock 3.3 one of our tests started crashing, it appears we were creating a nice class mock on NSMutableArray, we shouldn't probably be mocking foundation classes but this probably shouldn't cause a crash:

self.mockSortedObjects = [OCMockObject niceMockForClass:[NSMutableArray class]];

It seems like the next time [[NSMutableArray alloc] init] gets called we get a crash.

erikdoe commented 8 years ago

Could you provide a failing test? Or does this only occur in a complex scenario?

pwillsey commented 8 years ago

Here's an example of a test that reproduces the problem, it has a really long stack trace but it crashes in NSInvocation+OCMAdditions.m:55 on this line:

NSMutableArray *retainedArguments = [[NSMutableArray alloc] init];
@implementation TestOCMock

- (void)setUp {
    [super setUp];
    id arrayClassMock = [OCMockObject niceMockForClass:[NSMutableArray class]];
}

- (void)tearDown {
    [super tearDown];
}

- (void)testExample {
}

- (void)testPerformanceExample {
    [self measureBlock:^{
    }];
}

@end
erikdoe commented 8 years ago

Okay, this is an unintended and unexpected consequence of #235. In order to make OCMock somewhat thread-safe it was necessary to retain invocation arguments. The arguments that need to be retained are kept in an array. So, when the array class itself is mocked, any method send to the class goes through the new code that retains the arguments. That code tries to create an array to retain the arguments, which of course causes a class method on array to be invoked, which then goes to the retain arguments code... and we have an endless loop.

The only way out I can see is to stop OCMock from even trying to intercept class methods on NSArray, much like it aready does for NSString (see section 10.5 in the documentation). I've just pushed a workaround. Will wait for a few days if other issues come to light, and then release 3.3.1.

pwillsey commented 8 years ago

Thanks for your help!

erikdoe commented 8 years ago

Fixed and released by now.