我正在为我的核心数据应用设置单元测试。我在一个非常简单的测试中遇到了一个奇怪的问题。我得到的错误是:
/Developer/Tools/RunPlatformUnitTests.include:451:0 Test rig '/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.0.sdk/Developer/usr/bin/otest' exited abnormally with code 134 (it may have crashed).
我的单元测试的标题是:
#import <SenTestingKit/SenTestingKit.h>
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import "Unit.h"
@interface UnitLogicTests : SenTestCase {
NSManagedObjectContext *managedObjectContext;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
NSManagedObjectModel *managedObjectModel;
NSPersistentStore *persistentStore;
}
@end
实施是:
#import "UnitLogicTests.h"
@implementation UnitLogicTests
#pragma mark Setup and Teardown
- (void)setUp {
managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles: nil] retain];
NSLog(@"model: %@", managedObjectModel);
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel];
persistentStore = [persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType
configuration:nil
URL:nil
options:nil
error:NULL];
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:persistentStoreCoordinator];
}
- (void)tearDown
{
[managedObjectContext release];
managedObjectContext = nil;
NSError *error = nil;
STAssertTrue([persistentStoreCoordinator removePersistentStore:persistentStore error:&error],
@"couldn't remove persistent store: %@", error);
persistentStore = nil;
[persistentStoreCoordinator release];
persistentStoreCoordinator = nil;
[managedObjectModel release];
managedObjectModel = nil;
}
#pragma mark -
#pragma mark Test Cases
- (void)testThatEnvironmentWorks
{
STAssertNotNil(persistentStore, @"no persistent store");
}
- (void)testNewUnitDefaults {
Unit *newUnit = [NSEntityDescription insertNewObjectForEntityForName:@"Unit"
inManagedObjectContext:managedObjectContext];
STAssertEquals(newUnit.floorNumber, 1, @"Default value for new Unit's floor number should be 1");
}
@end
如果我省略- (void)testNewUnitDefaults
测试,那么构建完成没有错误,因此最后一次测试中的某些内容将其抛出一个循环。我是新手,所以非常感谢任何帮助!
感谢。
答案 0 :(得分:13)
我今天遇到了同样的问题,我认为Martin Brugger是对的,但如果你无法获得资源,还有一种替代方法可以获得bundle resrouce。
您可以尝试通过
获取捆绑包[NSBundle bundleForClass:[self class]]
这是我的核心数据单元测试工作的代码
NSBundle * bundle = [NSBundle bundleForClass:[self class]];
managedObjectModel_ = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:bundle]];
注意:请确保.xcdatamodel包含在您的单元测试目标中
答案 1 :(得分:2)
在你的测试用例周围添加@try .... catch块。
我认为用
加载模型[NSManagedObjectModel mergedModelFromBundles: nil]
没有按预期工作
使用您的代码初始化核心数据堆栈我得到了一个异常
+entityForName: could not locate an entity named 'Unit' in this model.
将模型初始化更改为以下代码可以正常工作:
// set according to the identifier in your modeltest Info.plist
NSString* path = [[NSBundle bundleWithIdentifier:@"com.yourcompany.ModelTest"]
pathForResource:@"CoreDataUnitTest_DataModel"
ofType:@"mom"];
NSURL* modelURL = [NSURL URLWithString:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
使用OCUnit进行单元测试有时会有点棘手,因为只有很少的错误信息会被曝光。
答案 2 :(得分: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: