My model is setup so Business has many clients, Client has one business. Inverse relationship is setup in the mom file.
I have a unit test like this:
- (void)testNewClientFromBusiness
{
PTBusiness *business = [modelController newBusiness];
STAssertTrue([[business clients] count] == 0, @"is actually %d", [[business clients] count]);
PTClient *client = [business newClient];
STAssertTrue([business isEqual:[client business]], nil);
STAssertTrue([[business clients] count] == 1, @"is actually %d", [[business clients] count]);
}
I implement -newClient
inside of PTBusiness like this:
- (PTClient *)newClient
{
PTClient *client = [NSEntityDescription insertNewObjectForEntityForName:@"Client" inManagedObjectContext:[self managedObjectContext]];
[client setBusiness:self];
[client updateLocalDefaultsBasedOnBusiness];
return client;
}
The test fails because [[business clients] count]
is still 0
after -newClient
is called.
If I impliment it like this:
- (PTClient *)newClient
{
PTClient *client = [NSEntityDescription insertNewObjectForEntityForName:@"Client" inManagedObjectContext:[self managedObjectContext]];
NSMutableSet *group = [self mutableSetValueForKey:@"clients"];
[group addObject:client];
[client updateLocalDefaultsBasedOnBusiness];
return client;
}
The tests passes.
My question(s): So am I right in thinking the inverse relationship is only updated when I interact with the mutable set? That seems to go against some other Core Data docs I've read. Is the fact that this is running in a unit test without a run loop have anything to do with it?
Any other troubleshooting recommendations? I'd really like to figure out why I can't set up the relationship at the client end.
Update: Some people have suggested I use -processPendingChanges
to for the relationships be updated before the end of the run loop where it typically happens. Doing this is not helping me. Another sample test that fails:
- (void)testAssigningRelationship
{
// BUG: for some unknow reason in this project i have to assign both ends of the relationsip manually.
NSURL *modelUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], @"PTDataModel.momd/schemaVersion1.mom"]];
NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl];
NSPersistentStoreCoordinator *persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel];
[persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:nil];
NSManagedObjectContext *managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:persistentStoreCoordinator];
PTBusiness *business = [NSEntityDescription insertNewObjectForEntityForName:@"Business" inManagedObjectContext:managedObjectContext];
STAssertTrue([[business clients] count] == 0, @"is actually %d", [[business clients] count]);
PTClient *client = [NSEntityDescription insertNewObjectForEntityForName:@"Client" inManagedObjectContext:managedObjectContext];
//NSMutableSet *clients = [business valueForKey:@"clients"];
//[clients addObject:client];
[client setBusiness:business];
[managedObjectContext processPendingChanges];
STAssertTrue([business isEqual:[client business]], @"[client business] is %@", [client business]);
// fails count is 0
STAssertTrue([[business clients] count] == 1, @"is actually %d", [[business clients] count]);
NSSet *clientSet = [business valueForKey:@"clients"];
// fails count is 0
STAssertTrue([clientSet count] == 1, @"is actually %d", [clientSet count]);
}
I've tried to recreate the bug in a fresh project that mirrors my own project's core data stack, but the fresh projects seem to work correctly. I'm really at a lose where to troubleshoot next. Sure I can work around this is my code (always use the mutableSet) but I worry about this being the tip of a bigger problem.