Ошибка построения основного стека данных в модульных тестах - PullRequest
2 голосов
/ 15 июля 2010

Я пытаюсь начать модульное тестирование приложения, использующего Core Data. В методе setUp моего первого теста я могу получить путь к моей модели данных, но по какой-то причине не могу преобразовать ее в NSURL.

Мой метод установки:

- (void)setUp {

    NSBundle *bundle = [NSBundle bundleWithIdentifier:@"com.testcompany.LogicTests"];
    STAssertNotNil(bundle, @"Error finding bundle to create Core Data stack.");

    NSString *path = [bundle pathForResource:@"DataModel" ofType:@"momd"];
    STAssertNotNil(path, @"The path to the resource cannot be nil.");

    NSURL *modelURL = [NSURL URLWithString:path];
    STAssertNotNil(modelURL, @"The URL to the resource cannot be nil. (tried to use path:%@, modelURL is %@)", path, modelURL);

    ...

}

Я получаю ошибку:

/Users/neall/iPhone Apps/TestApp/UnitLogicTests.m:24:0 "((modelURL) != nil)" should be true. The URL to the resource cannot be nil. (tried to use path:/Users/neall/iPhone Apps/TestApp/build/Debug-iphonesimulator/LogicTests.octest/DataModel.momd, modelURL is (null))

Я проверил файловую систему, и каталог /Users/neall/iPhone Apps/TestApp/build/Debug-iphonesimulator/LogicTests.octest/DataModel.momd существует.

Что мне здесь не хватает?

Спасибо!

Ответы [ 4 ]

3 голосов
/ 15 июля 2010

Попробуйте использовать [NSURL fileURLWithPath:path] вместо того, чтобы создать URL

0 голосов
/ 22 июля 2014

После нескольких часов, проведенных в июле 2014 года, этот пост был одним из нескольких, которые частично привели меня к рабочему решению.Нам каким-то образом удалось сломать удивительно хрупкий (и загадочный) механизм, который связывает пакет, в котором находится ваш исходный код, с пакетом, который выполняет модульное тестирование.Кроме того, у вас может быть неправильно названная xcdatamodel.См. Комментарии для объяснений:

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

Вот как вы можете использовать вышеуказанный контекст:

-(void)testMyStuff
{

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

В заключение, вам также может понадобиться добавить свои исходные файлы и xcmodel в разделеИсточники компиляции »этапов сборки.К сожалению, это меняется практически с каждой версией Xcode.Для Xcode 5:

xcode 5 build phases

0 голосов
/ 29 апреля 2013

xcdatamodel также следует добавить в Project -> Targets -> "цель модульного тестирования" -> фазы сборки -> исходники компиляции

0 голосов
/ 15 июля 2010

Дважды проверьте, что вы видите каталог с именем DataModel.momd по адресу / Users / neall / iPhone Apps / TestApp / build / Debug-iphonesimulator / LogicTests.octest / DataModel.momd.

Если вы добавите файл xcdatamodel с помощью команды «Добавить новый файл ...» в XCode, у вас будет только один файл, и это будет DataModel.mom (без конечного d). Если это так, измените

NSString *path = [bundle pathForResource:@"DataModel" ofType:@"momd"];

до

NSString *path = [bundle pathForResource:@"DataModel" ofType:@"mom"];

исправит вашу непосредственную проблему.

Вы хотите использовать файл ULWithPath: который также предложил Клаус.

Если вы хотите в будущем управлять версией вашей модели, и в настоящее время у вас есть только файл .mom, выберите файл DataModel.xcdatamodel в XCode и перейдите в Проектирование -> Модель данных -> Добавить версию модели. Это приведет к созданию каталога DataModel.momd с файлом DataModel.mom. Вы можете просто удалить новую версию, добавленную в этот каталог, и ваши исходные тесты будут работать.

...