现在我正在使用核心数据如何unit testing我的模型?

我一直在开发一个使用领域模型的iphone应用程序,并推迟了应用程序的持久性方面。 核心数据看起来像是一个非常好的解决scheme,因为我已经有了一个定义良好的模型,但是我现在正在用现有的unit testing来解决问题。

这里是我现在拥有的简单例子:

- (void)test_full_name_returns_correct_string { Patient *patient = [[Patient alloc] init]; patient.firstName = @"charlie"; patient.lastName = @"chaplin"; STAssertTrue([[patient fullName] isEqualToString:@"charlie chaplin"], @"should have matched full name"); } 

我的Patient对象从NSManagedObject扩展到firstName和lastName属性使用@dynamic时,我该如何做到这一点?

有没有其他人遇到这种types的核心数据? 谢谢。

您需要在每个方法内或在-setUp构build一个Core Data堆栈,然后将其拆卸下来。 使用NSInMemoryPersistentStore可以为unit testing保持快速和内存。 添加一个@property (nonatomic,retain) NSManagedObjectContext *moc到你的TestCase子类。 然后:

 - (void)setUp { NSManagedObjectModel *mom = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:bundleContainingXCDataModel]]; NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom]; STAssertTrue([psc addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:NULL] ? YES : NO, @"Should be able to add in-memory store"); self.moc = [[NSManagedObjectContext alloc] init]; self.moc.persistentStoreCoordinator = psc; [mom release]; [psc release]; } - (void)tearDown { self.moc = nil; } 

你的testing方法如下所示:

 - (void)test_full_name_returns_correct_string { Patient *patient = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.moc]; patient.firstName = @"charlie"; patient.lastName = @"chaplin"; STAssertTrue([[patient fullName] isEqualToString:@"charlie chaplin"], @"should have matched full name"); } 

假设你的实体被命名为Person 。 顺便说一下,在你的版本的方法中有一个内存泄漏; 在非核心数据版本中,患者应该是-releaseinsertNewObjectForEntityForName:managedObjectContext:返回一个自动发布的实例)。

我使用了Barry Wark的上述答案,但是我必须做一些修改才能使其与当前项目XCode5,iOS7一起工作。

该物业保持不变:

 @interface SIDataTest : XCTestCase @property (nonatomic,retain) NSManagedObjectContext *moc; @end 

安装程序必须首先更改为不发布,其次提供模型URL。

 - (void)setUp { [super setUp]; NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"SimpleInvoice" withExtension:@"momd"]; NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom]; XCTAssertTrue([psc addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:NULL] ? YES : NO, @"Should be able to add in-memory store"); self.moc = [[NSManagedObjectContext alloc] init]; self.moc.persistentStoreCoordinator = psc; } 

以下是示例testing用例:

 - (void)testCreateNew { Invoice *newInvoice = [NSEntityDescription insertNewObjectForEntityForName:@"Invoice" inManagedObjectContext:self.moc]; newInvoice.dueDate = [NSDate date]; NSString* title = [[NSString alloc] initWithFormat:@"Invoice %@", @112]; newInvoice.title = title; // Save the context. NSError *error = nil; if (![self.moc save:&error]) { // Replace this implementation with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. XCTFail(@"Error saving in \"%s\" : %@, %@", __PRETTY_FUNCTION__, error, [error userInfo]); } XCTAssertFalse(self.moc.hasChanges,"All the changes should be saved"); }