How to unit test my models now that I am using Core Data?

I am developing an iphone application using a domain model and still put off the persistence aspect of the application. Core Data looks like a really good solution, since I already have a well-defined model, but I ran into a problem with my current unit tests.

Here is a simple example of what I have now:

- (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"); } 

How can I do this work as soon as the Patient is removed from NSManagedObject and uses @dynamic for the firstName and lastName properties?

Does anyone else encounter this type of data using Core Data? Thank.

+55
objective-c unit-testing core-data
Dec 04 '09 at 21:37
source share
2 answers

You need to create a Core Data stack, either inside each method, or in -setUp , and then tear it down. Using NSInMemoryPersistentStore will keep things fast and in memory for your unit tests. Add @property (nonatomic,retain) NSManagedObjectContext *moc to your TestCase subclass. Then:

 - (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; } 

Then your test method looks like this:

 - (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"); } 

assuming your object is named Person . By the way, a memory leak occurred in your version of the method; the patient must be -release 'd in the version of the non-server data ( insertNewObjectForEntityForName:managedObjectContext: returns an instance with auto-implementation).

+83
Dec 04 '09 at 22:16
source share

I used the answer above, Barry Work, but I had to make some changes to make it work with current Xcode5, iOS7 projects.

The property remains the same:

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

The setting was, first of all, to change, so as not to release, and secondly, to provide the URL of the model.

 - (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; } 

Here is a test case example:

 - (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"); } 
+21
Jun 02 '14 at 5:56 on
source share



All Articles