Crash when calling trying to mock mutableCopy on NSString.

Discussion of the OCMock framework. If you have patches we would prefer you to send them to the mailing list, but attaching them to a topic is possible, too.

Crash when calling trying to mock mutableCopy on NSString.

Postby DrDots » 12 Mar 2013, 12:00

I'm trying to mock a call to `mutableCopy` using OCMock and GHUnit on iOS.

Despite the test passing, I get an `EXC_BAD_ACCESS` exception during the cleanup, and I'm trying to work out why.

Take a look at this. This test shows that it is possible to mock `mutableCopy` on a mock `NSString`. In this test I return another `NSString`, not an `NSMutableString`. This is just to demonstrate that the `mutableCopy` expectation is fired, and the test passes.

#import <GHUnitIOS/GHUnit.h>
#import "OCMock.h"

@interface TestItClass : GHTestCase @end
@implementation TestItClass

// Test that mutableCopy on an NSString is mockable.
- (void)test_1_mutableCopyOfString_shouldBeMockable_givenAStringIsReturned {
NSString *string = [OCMockObject mockForClass:NSString.class];
NSString *copy = @"foo";
[(NSString *) [[(id) string expect] andReturn:copy] mutableCopy];

// MutableCopy is mocked to return a string, not a mutable string!
// This is clearly wrong from a static typing point of view, but
// the test passes anyway, which is ok.
NSMutableString *result = [string mutableCopy];
GHAssertEquals(result, copy, nil);
[(id)string verify];

Now I change the mock expectation so that `mutableCopy` now returns an `NSMutableString`. The test still passes, but on the tear down of the test I get a `EXC_BAD_ACCESS` exception.

- (void)test_2_mutableCopyOfString_shouldBeMockable_givenAMutableStringIsReturned {
NSString *string = [OCMockObject mockForClass:NSString.class];
NSMutableString *copy = [@"foo" mutableCopy];
[(NSString *) [[(id) string expect] andReturn:copy] mutableCopy];

// Now mutableCopy is mocked to return a mutable string!
// The test now blows up during the test teardown! Why?
NSMutableString *foo = [string mutableCopy];
GHAssertEquals(foo, copy, nil);
[(id)string verify];


In both tests the verifies work, as to the asserts. This shows that both tests are well constructed and that the mock expectations are being fired as expected. However, the second test fails in the tear down with a bad memory access:

Simulator session started with process 7496
Debugger attached to process 7496
2013-03-11 18:23:05.519 UnitTests[7496:c07] TestItClass/test_2_mutableCopyOfString_shouldBeMockable_givenAMutableStringIsReturned ✘ 0.00s
2013-03-11 18:23:06.466 UnitTests[7496:c07] Re-running: TestItClass/test_2_mutableCopyOfString_shouldBeMockable_givenAMutableStringIsReturned <GHTest: 0x7793340>
Exception: EXC_BAD_ACCESS (code=1, address=0x11dfe3ea))

Can you please suggest to me why it might be happening? (I have just updated to the latest OCMock from git, but it still has the same problem).


Re: Crash when calling trying to mock mutableCopy on NSStrin

Postby taoy » 12 Mar 2013, 12:04

This was posted by me, but I forgot to login so it isn't associated with my account.
Posts: 4
Joined: 10 Sep 2012, 08:25

Re: Crash when calling trying to mock mutableCopy on NSStrin

Postby Guest » 14 Mar 2013, 09:43

I've found the problem. It appears that my ARC managed test is releasing the mock object that was returned by the mutableCopy call.

I've proposed a fix in GItHub.


Return to OCMock