Модульному тесту не удается найти файл модели базовых данных - PullRequest
16 голосов
/ 14 апреля 2011

Я создал проект с моделью Core Data.Приложение ищет файл модели (.momd) и работает нормально.

К сожалению, модульный тест продолжает возвращать ноль:

NSURL *dataModelURL = [[NSBundle mainBundle] URLForResource:@"myDataModel" withExtension:@"momd"];

Я вижу папку и файл myDataModel.xdatamodeldв ОБА основной каталог и каталог Compile Sources цели модульного тестирования - но этого, кажется, недостаточно.Что еще мне не хватает в модульном тесте?

Спасибо, -Лютер

Ответы [ 5 ]

35 голосов
/ 18 апреля 2012

К сожалению, цель модульного теста не использует основной пакет приложения, но создает специальный пакет UnitTest.Поэтому, если вам нужно использовать связанные ресурсы (например, модель базовых данных) в своих тестах, вам нужно обойти эту проблему.

Самый простой и самый гибкий обходной путь - это использование bundleForClass: метода NSBundle в вашем тестовом коде.Параметр для этого метода может быть просто задан как [self class] в ваших тестах.Таким образом, вы можете повторно использовать этот код, не настраивая идентификаторы пакета в нескольких проектах.

Пример:

- (void)testBundleLocation
{
    NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    NSURL *url = [bundle URLForResource:@"myDataModel" withExtension:@"momd"];
    ...
}
6 голосов
/ 14 апреля 2011

Ответ связан с комплектом.Цель юнит-теста не использует основной пакет.Он создает свой собственный пакет, который в моем случае по умолчанию равен com.yourcompany.UnitTest - прямо из [Target] -info.plist.

Исправленное решение затем выглядит так:

NSBundle *bundle = [NSBundle bundleWithIdentifier:@"com.yourcompany.UnitTests"];
NSURL *url = [bundle URLForResource:@"myDataModel" withExtension:@"momd"];

Спасибо

3 голосов
/ 26 февраля 2014

Была похожая проблема, я решил ее с помощью фреймворка OCMock, поэтому мне не нужно было менять код приложения

@interface TestCase()
    @property (nonatomic, strong) id bundleMock;
@end

@implementation TestCase

- (void)setUp
{
    self.bundleMock = [OCMockObject mockForClass:[NSBundle class]];
    [[[self.bundleMock stub] andReturn:[NSBundle bundleForClass:[self class]]] mainBundle];
    [super setUp];
}

- (void)tearDown
{
    [self.bundleMock stopMocking];
    [super tearDown];
}
2 голосов
/ 03 октября 2011

Этот метод получит ваш комплект от любой цели. Однако для каждой цели, которую вы добавляете, вы должны вручную добавить идентификатор пакета plist в массив identifiers, потому что нет способа получить его программно. Преимущество заключается в том, что вы можете использовать один и тот же код для тестирования или запуска приложения.

+(NSBundle*) getBundle 
{
    NSBundle *bundle = nil;

    // try your manually set bundles
    NSArray *identifiers = [NSArray arrayWithObjects: @"com.your.application",
                                                      @"com.your.test",
                                                      nil];
    for(NSString *bundleId in identifiers) {
        bundle = [NSBundle bundleWithIdentifier:bundleId];
        if (bundle!=nil) break;
    }

    // try the main bundle
    if (bundle==nil) bundle = [NSBundle mainBundle];

    // abort
    assert(bundle!=nil && "Missing bundle. Check the Bundle identifier on 
           the plist of this target vs the identifiers array in this class.");

    return bundle;
}
0 голосов
/ 04 января 2018

Моя проблема была действительно неправильной Связкой! Поскольку я пытался использовать базу данных из / в Framework, я просто загружал БД из соответствующего Bundle!

Вот код в Swift4, использующий MagicalRecord:

// Load the bundle
let frameworkBundle = Bundle(for: AClassFromTheFramework.self)
let managedObjectModel = NSManagedObjectModel.mergedModel(from: [frameworkBundle])
// Use the new `managedObjectModel` by default
MagicalRecord.setShouldAutoCreateManagedObjectModel(false)
NSManagedObjectModel.mr_setDefaultManagedObjectModel(managedObjectModel)
// Load the database 
MagicalRecord.setupCoreDataStack(withAutoMigratingSqliteStoreNamed: "db.sqlite")

И вуаля!

...