我正在尝试在iOS上使用OCMock和GHUnit模拟对mutableCopy的调用。

尽管通过了测试,但在清理过程中仍收到EXC_BAD_ACCESS异常,因此我试图找出原因。

看看这个。该测试表明可以在模拟mutableCopy上模拟NSString。在此测试中,我返回另一个NSString,而不是NSMutableString。这只是为了证明mutableCopy期望被触发,并且测试通过了。

#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];
}

现在,我更改了模拟期望值,以便mutableCopy现在返回NSMutableString。测试仍然通过,但是在拆卸测试中,我收到了EXC_BAD_ACCESS异常。
- (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];
}

@end

在这两个测试中,对于断言,验证工作正常。这表明这两个测试的构造都很好,并且模拟预期已按预期进行。但是,第二项测试由于内存访问不正确而失败:
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))

您能告诉我为什么会发生这种情况吗?

谢谢,

最佳答案

您面临的问题是由ARC遵循Basic Memory Management Rules引起的。具体来说:


  • 您拥有创建的任何对象

    使用名称以“alloc”,“new”,“copy”或“mutableCopy”开头的方法(例如alloc,newObject或mutableCopy)创建对象。


  • 因此,解决方案是查看调用选择器,以确定是否对retain进行returnValue

    希望对您有所帮助。

    09-27 17:05