我正在尝试开始使用Core Data进行单元测试。在我的单元第一次测试的setUp方法中,我可以获得我的数据模型的路径,但由于某种原因无法将其转换为NSURL。
我的setUp方法是:
- (void)setUp {
NSBundle *bundle = [NSBundle bundleWithIdentifier:@"com.testcompany.LogicTests"];
STAssertNotNil(bundle, @"Error finding bundle to create Core Data stack.");
NSString *path = [bundle pathForResource:@"DataModel" ofType:@"momd"];
STAssertNotNil(path, @"The path to the resource cannot be nil.");
NSURL *modelURL = [NSURL URLWithString:path];
STAssertNotNil(modelURL, @"The URL to the resource cannot be nil. (tried to use path:%@, modelURL is %@)", path, modelURL);
...
}
我得到的错误是:
/Users/neall/iPhone Apps/TestApp/UnitLogicTests.m:24:0 "((modelURL) != nil)" should be true. The URL to the resource cannot be nil. (tried to use path:/Users/neall/iPhone Apps/TestApp/build/Debug-iphonesimulator/LogicTests.octest/DataModel.momd, modelURL is (null))
我检查了文件系统,目录/Users/neall/iPhone Apps/TestApp/build/Debug-iphonesimulator/LogicTests.octest/DataModel.momd
已存在。
我在这里缺少什么?
谢谢!
答案 0 :(得分:3)
尝试使用[NSURL fileURLWithPath:path]
来构建网址
答案 1 :(得分:0)
仔细检查您是否在/ Users / neall / iPhone Apps / TestApp / build / Debug-iphonesimulator / LogicTests.octest / DataModel.momd中看到名为DataModel.momd的目录。
如果您通过Xcode中的Add New File ...命令添加了一个xcdatamodel文件,那么您将只有一个文件,它将是DataModel.mom(没有尾随d)。如果是这种情况,请更改
NSString *path = [bundle pathForResource:@"DataModel" ofType:@"momd"];
到
NSString *path = [bundle pathForResource:@"DataModel" ofType:@"mom"];
将解决您的直接问题。
你想使用Claus建议的fileURLWithPath:
如果您希望将来对模型进行版本控制,并且您目前只有.mom文件,请在XCode中选择您的DataModel.xcdatamodel文件,然后转到Design - >数据模型 - >添加模型版本。这将强制创建包含DataModel.mom文件的DataModel.momd目录。您可以删除它添加到该目录中的新版本,并且您的原始测试将起作用。
答案 2 :(得分:0)
xcdatamodel也应添加到 项目 - >目标 - > “单元测试目标” - >构建阶段 - >编译来源
答案 3 :(得分:0)
在2014年7月花了几个小时后,这篇文章是几个部分导致我找到工作解决方案之一。 我们设法打破了令人惊讶的脆弱(和神秘)机制,它将源代码所在的bundle链接到运行单元测试的bundle。此外,您可能有一个名不副实的xcdatamodel。请参阅注释以获取解释:
-(NSManagedObjectContext *) getManagedObjectContext
{
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
//Replace MyClass with class that is from your data model
//really any of your classes should work
NSBundle * bundle = [NSBundle bundleForClass:[MyClass class]];
//You can uses this line to figure you what your bundle is actually named
//In my case the because my PRODUCT_NAME had spaces in it they was replaced with '-'
//(dashes) and I couldn't divine it from the info.plist and the Build Settings.
NSString * ident =[bundle bundleIdentifier];
//This will show you where your app is actually out building temporary files
//The exact location appears to change every version or to of Xcode so
//this is useful for figuring out what your model is named
NSString * bundlePath =[bundle bundlePath];
//Here replace Name_of_model_without_the_dot_xcdatamodel with the name of your
//xcdatamodel file without an extension
//Some tutorials will have you use AppName.xcdatamodel others will simply name it
//DataModel.xcdatamodel.
//In any event if bothe path and path1 return null then check the
//bundlePath by going to Finder and pressing Command-Shift-G and pasting
//bundlePath into the pop-up. Look around for a mom or momd file thats the name you want!
NSString* path = [bundle
pathForResource:@"Name_of_model_without_the_dot_xcdatamodel"
ofType:@"momd"];
//If the above 'path' and 'path1' is not then you want to use this line instead
NSString* path1 = [bundle
pathForResource:@"Name_of_model_without the_dot_xcdatamodel"
ofType:@"mom"];
//the above path lines are simply so you can trace if you have a mom or a momd file
//replace here appropriately
NSURL *modelURL = [bundle URLForResource:@"Name_of_model_without the_dot_xcdatamodel"
withExtension:@"momd"];
//the rest is boiler plate:
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSPersistentStoreCoordinator *psc =
[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
[psc addPersistentStoreWithType:NSInMemoryStoreType
configuration:nil URL:nil options:nil error:nil];
[moc setPersistentStoreCoordinator:psc];
return moc;
}
以下是您可以使用上述内容的方法:
-(void)testMyStuff
{
NSManagedObjectContext* context=[self getManagedObjectContext];
MyClass *myobj=[NSEntityDescription insertNewObjectForEntityForName:@"MyClass"
inManagedObjectContext:context];
}
最后请注意,您可能还需要在"编译源"下添加源文件和xcmodel。构建阶段。不幸的是,这几乎与每个版本的Xcode都有所不同。对于Xcode 5: