开发者

Unit Testing Core Data - exited abnormally with code 134

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 cras开发者_JS百科hed).

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.


I got the same problem today, and I think Martin Brugger is right, but there is also an alternative method for getting bundle resrouce, if you could not get resource.

you can try get the bundle by

[NSBundle bundleForClass:[self class]]

here is my code to make the core data unit test work

NSBundle * bundle = [NSBundle bundleForClass:[self class]];
managedObjectModel_ = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:bundle]];

NOTE: pls also ensure .xcdatamodel is included in your unit test target


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.


After spending several hours stacking in July 2014 this post was one of several that in part led me to the working solution. We somehow managed to break the surprisingly fragile (and mysterious) mechanism that links the bundle that your source code lives in to the bundle that runs the unit test. Further you might have a misnamed xcdatamodel. See comments for explanations:

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

Here is how you might use the above context:

-(void)testMyStuff
{

   NSManagedObjectContext* context=[self getManagedObjectContext];
   MyClass *myobj=[NSEntityDescription insertNewObjectForEntityForName:@"MyClass"   
   inManagedObjectContext:context];
}

One final note you may also have to add your source files and xcmodel under the "Compile Sources" of build phases. This unfortunately changes with almost every version of Xcode. For Xcode 5:

Unit Testing Core Data - exited abnormally with code 134

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜