gpt4 book ai didi

cocoa - 带有 Core Data/Mogenerator 的 OCMock 抛出异常 NSInvalidArgumentException [NSProxy doesNotRecognizeSelector]

转载 作者:行者123 更新时间:2023-12-03 16:58:22 25 4
gpt4 key购买 nike

我在单元测试中使用 OCMock 来模拟 NSManagedObjects。我使用 Mogenerator 为我的核心数据对象生成机器和人类可读的文件。我试图模拟 NSManagedObject 以返回 bool 值和字符串。两者都是我的核心数据实体的属性。当我模拟 BOOL 时,该值从对象正确返回,我的类使用它,并且测试成功通过。当我尝试在同一对象上 stub NSString 属性时,它会抛出 NSInvalidArgumentException [NSProxy doesNotRecognizeSelector]

调用代码如下:

id biller = [OCMockObject mockForClass:[Biller class]];
// passes
[[[biller stub] andReturnValue:OCMOCK_VALUE((BOOL){NO})] billerValidatedValue];
// throws exception
[[[biller stub] andReturn:@"Test"] name];

这是一个异常(exception):

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSProxy doesNotRecognizeSelector:name] called!'

我知道有some recommendations为了测试目的,有一个位于 NSManagedObject 前面的接口(interface),但这似乎增加了 Mogenerator 机器/人类文件之上的复杂性。

在不完全重新配置此代码的情况下,还有其他建议吗?该代码已经投入生产,我们正在尝试在开发新功能时添加单元测试。

最佳答案

问题的关键是您的核心数据模型在测试中不可用,因此当您尝试对读取的属性进行 stub 时,该方法不存在。 Core Data 在运行时动态拦截属性访问器。

要使模型可用,您需要确保 .xcdatamodeld 包含在单元测试目标中,并且需要在测试中设置模型。我不确定您是否能够模拟动态属性,但在测试中对 Core Data 对象执行 CRUD 操作变得微不足道,因此无需模拟它们。以下是在测试中初始化模型的一种方法:

static NSManagedObjectModel *model;
static NSPersistentStoreCoordinator *coordinator;
static NSManagedObjectContext *context;
static NSPersistentStore *store;

-(void)setUp {
[super setUp];
if (model == nil) {
@try {
NSString *modelPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"my-model" ofType:@"mom"];
NSURL *momURL = [NSURL fileURLWithPath:modelPath];
model = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
}
@catch (NSException *exception) {
NSLog(@"couldn't get model from bundle: %@", [exception reason]);
@throw exception;
}
}
coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
NSError *error;
store = [coordinator addPersistentStoreWithType: NSInMemoryStoreType
configuration: nil
URL: nil
options: nil
error: &error];
assertThat(store, isNot(nil));
context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:coordinator];
}

-(void)tearDown {
// these assertions ensure the test was not short-circuited by a failure to initialize the model
assertThat(model, isNot(nil));
assertThat(context, isNot(nil));
assertThat(store, isNot(nil));
assertThat(coordinator, isNot(nil));
NSError *error = nil;
STAssertTrue([coordinator removePersistentStore:store error:&error],
@"couldn't remove persistent store: %@", [error userInfo]);
[super tearDown];
}

或者,您可以使用 MagicalRecord 来显着简化事情。 。即使您不在应用程序中使用它,您也可以在测试中使用它来封装所有核心数据设置。这是我们的单元测试设置在使用 MagicalRecord 的应用程序中的样子:

-(void)setUp {
[super setUp];
[MagicalRecordHelpers setupCoreDataStackWithInMemoryStore];
}

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

关于cocoa - 带有 Core Data/Mogenerator 的 OCMock 抛出异常 NSInvalidArgumentException [NSProxy doesNotRecognizeSelector],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12697058/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com