OCMock 抛出 EXC_BAD_ACCESS

Posted

技术标签:

【中文标题】OCMock 抛出 EXC_BAD_ACCESS【英文标题】:OCMock throwing EXC_BAD_ACCESS 【发布时间】:2016-06-16 16:05:00 【问题描述】:

我刚刚下载了 OCMock 用于测试我正在开发的库。我在尝试做的第一个存根中遇到了问题。我有一个处理所有网络操作的对象,我有另一个对象,它有一个地图,它在其中绘制接收到的信息。我想模拟网络对象来测试地图对象。

这是我的测试文件:

@interface STMap ()

@property (retain) STNetwork* router;

@end

@interface testSTMap : XCTestCase <STMapDelegate>

@property (retain) MKMapView* mapView;
@property (retain) STMap* testMap;
@property (retain) id mockRouter;

@end

@implementation testSTMap

- (void)setUp 
    [super setUp];
    // Put setup code here. This method is called before the invocation of each test method in the class.
    self.mapView = [[MKMapView alloc] init];
    self.testMap = [[STMap alloc] initWithDelegate:self andKey:@"test" andRouteOptions:nil
                                            andMap:self.mapView andOverlayLevel:MKOverlayLevelAboveLabels];
    self.mockRouter = OCMClassMock([STNetwork class]);
    self.testMap.router = self.mockRouter;


- (void)testExample 
    // This is an example of a functional test case.
    // Use XCTAssert and related functions to verify your tests produce the correct results.
    OCMStub([self.mockRouter getRouteForStartLat:[OCMArg any] andStartLon:[OCMArg any]
                                       andEndLat:[OCMArg any] andEndLon:[OCMArg any]])._andReturn(nil);
    [self.testMap addRouteForStartLat:@0 andStartLon:@0 andEndLat:@1 andEndLon:@1];

如您所见,我保留了所有 3 个属性,因此错误不是来自测试本身。我的地图对象具有私有属性,包括网络对象,这就是为什么我在测试中创建了一个扩展以便能够将其更改为模拟对象。此时,我什至还没有调用地图对象,所以我不会发布它的代码。

网络对象如下所示(所有属性都是私有的):

@interface STNetwork ()

@property (retain) NSString* url;
@property (weak) id<STNetworkDelegate> delegate;
@property (retain) NSString* key;
@property (copy) CompletionBlock completionHandler;

@end

我知道委托属性必须很弱才能避免保留循环,所以我怀疑这是导致错误的原因。

错误在OCMStub 行中抛出。追踪:

OCMStubRecorder.m- 第 112 行:if(OCMIsObjectType([aValue objCType]))。此时aValue为nil,这就是问题的开始,但我不知道aValue是从哪里来的。 OCMFunctions.m 第 78 行:const char *unqualifiedObjCType = OCMTypeWithoutQualifiers(objCType);。这里,objCType 为 NULL,正如预期的那样,因为 aValue 为 nil。 OCMFunctions.m 第 40 行:while(strchr("rnNoORV", objCType[0]) != NULL)。这是错误访问实际发生的地方。

我尝试过的事情:

将 [OCMArg any] 更改为硬编码值 从 mock 中返回一个数字、NSNull 和 void

这些都没有让我通过不良访问。非常感谢任何帮助!

- (void)getRouteForStartLat: (NSNumber*) startLat
                andStartLon: (NSNumber*) startLon
                  andEndLat: (NSNumber*) endLat
                  andEndLon: (NSNumber*) endLon;

【问题讨论】:

能否提供getRouteForStartLat:andStartLon:andEndLat:andEndLon:方法的声明? @ErikDoernenburg 我添加了您要求的声明 【参考方案1】:

您是否尝试过使用andReturn()?带下划线前缀的版本仅供内部使用。

【讨论】:

哇!我不敢相信修复如此简单。我什至不知道为什么我把下划线放在第一位。现在当我做andReturn(nil) 时它可以工作,但由于声明是void,我想返回void。但是,andReturn(void) 给了我编译错误“变量的类型不完整 'typeof(void)'”和“预期表达式”。是否可以返回无效? 如果没有什么可返回的,请不要使用andReturn()

以上是关于OCMock 抛出 EXC_BAD_ACCESS的主要内容,如果未能解决你的问题,请参考以下文章

XCode - iOS - <OCMock/OCMock.h> 文件未找到

OCMock 对带有参数的方法进行 OCMock 并返回一个值

无法识别 OCMock 的头文件

OCMock:模拟协议未正确停止

OCMock 验证失败

OCMock:存根 @dynamic 属性