views:

151

answers:

1

Hello all,

I am setting up unit testing for my core data app. I'm running into a strange problem in a pretty simple test. The error I'm getting is:

/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).

The header for my unit tests is:

#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

The implementation is:

#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

If I omit the - (void)testNewUnitDefaults test, then the build completes without errors, so something in that last test is throwing it for a loop. I am new to this, so any assistance would be greatly appreciated!

Thanks.

+1  A: 

put a @try .... catch block around your testcase.

I think loading the model with

[NSManagedObjectModel mergedModelFromBundles: nil]

did not work as expected

Using your code for initialization of the core data stack I got an exception

+entityForName: could not locate an entity named 'Unit' in this model.

Changing the model initialization to the following code works fine:

    // 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];

Unit Tests with OCUnit sometimes are a bit tricky as only little information on errors is exposed.

Martin Brugger
Thanks Martin, I think you're right. I still can't quite get it to find the correct path though. I added a line: `STAssertNotNil(path, @"The path to the resource cannot be nil.");` after your suggested code, and it's erroring there. I've checked that `[NSBundle bundleWithIdentifier:@"com.testcompany.AppLogicTests"]` is not nil, so that only leaves the name for the resource for me to have messed up. What's the magical resource name (or how do I find it) that will get things running? Thanks.
Neal L
pathForResource: "$name" is the name of your datamodel file.you also have to add the datamodel to the unit test target"$name.xdatamodel" within your project (.xcdatamodeld for versioned data models)ofType: @"mom" or @"momd"Probably take a look at my project with unit tests at http://github.com/mbrugger/CoreDataDependentProperties/tree/master/LPAutomatedObserving/Tests/
Martin Brugger
Adding to "put a @try .... catch block around your testcase" above: the exception is probably being written to Console, so have a look in there for the unhandled exception.
Martin Dow