OCMock 投掷 EXC_BAD_ACCESS
OCMock throwing EXC_BAD_ACCESS
我刚刚下载了 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 个属性,因此错误不是来自测试本身。我的地图对象具有私有属性,包括网络对象,这就是为什么我在测试中创建了一个扩展以便能够将其更改为模拟对象。此时,我什至还没有调用地图对象,所以我不会 post 它的代码。
网络对象如下所示(所有属性都是私有的):
@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] 更改为硬编码值
- 从模拟中返回一个数字、NSNull 和 void
None 这些让我克服了错误的访问。非常感谢任何帮助!
- (void)getRouteForStartLat: (NSNumber*) startLat
andStartLon: (NSNumber*) startLon
andEndLat: (NSNumber*) endLat
andEndLon: (NSNumber*) endLon;
您尝试过使用 andReturn()
吗?带下划线前缀的版本仅供内部使用。
我刚刚下载了 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 个属性,因此错误不是来自测试本身。我的地图对象具有私有属性,包括网络对象,这就是为什么我在测试中创建了一个扩展以便能够将其更改为模拟对象。此时,我什至还没有调用地图对象,所以我不会 post 它的代码。
网络对象如下所示(所有属性都是私有的):
@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] 更改为硬编码值
- 从模拟中返回一个数字、NSNull 和 void
None 这些让我克服了错误的访问。非常感谢任何帮助!
- (void)getRouteForStartLat: (NSNumber*) startLat
andStartLon: (NSNumber*) startLon
andEndLat: (NSNumber*) endLat
andEndLon: (NSNumber*) endLon;
您尝试过使用 andReturn()
吗?带下划线前缀的版本仅供内部使用。