Классы Модели Поблочного тестирования, которые наследовались NSManagedObject

Так... Я пытаюсь разбудить набор модульных тестов в своем приложении для iPhone, но у меня есть некоторые проблемы. Я пытаюсь протестировать свои образцовые классы, но они наследовались непосредственно NSManagedObject. Я уверен, что это - проблема, но я не знаю, как обойти ее.

Все создает и работает как ожидалось, но я получаю эту ошибку при вызове любого метода на классе, который я тестирую:

Unknown.m:0:0 unrecognized selector sent to instance 0xc2b120

Если я следую за этой структурой для создания моего объекта в моих тестах, я заканчиваю с другой ошибкой полностью, но это все еще не помогает мне.

Если я инстанцирую своей модели как это:

entry = [[TimeEntry alloc]
        initWithEntity:nil
        insertIntoManagedObjectContext:nil];

Затем я заканчиваю с этой ошибкой во времени выполнения:

An NSManagedObject of class 'TimeEntry' must have a valid NSEntityDescription.

Если я пробую его как это:

entry = [[TimeEntry alloc] init];

Затем я заканчиваю с этой ошибкой:

unrecognized selector sent to instance 0xc2b120

И если я следую за шаблоном, положенным здесь:

model = [[NSManagedObjectModel mergedModelFromBundles: nil] retain];
NSLog(@"model: %@", model);
coord = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: model];
store = [coord addPersistentStoreWithType: NSInMemoryStoreType
                            configuration: nil
                                      URL: nil
                                  options: nil 
                                    error: NULL];
ctx = [[NSManagedObjectContext alloc] init];
[ctx setPersistentStoreCoordinator: coord];

entry = (TimeEntry *)[NSEntityDescription insertNewObjectForEntityForName:@"TimeEntry" inManagedObjectContext:ctx];

Затем я получаю эту ошибку:

could not locate an entity named 'TimeEntry' in this model.

В основном мой вопрос - это: как я могу протестировать класс, который наследовался NSManagedObject?

6
задан Matt Baker 16 May 2010 в 14:04
поделиться

3 ответа

Чтобы создать экземпляр NSManagedObject, вам понадобится сущность. Таким образом, то, что вы пробовали сначала - передать nil для объекта или использовать голый -init (который не поддерживается в NSManagedObject) - не сработало. Вы поступаете правильно, используя - [NSEntityDescription insertNewObjectForEntityForName: inManagedObjectContext:] для создания объекта, вам просто нужно:

  1. Убедитесь, что объект TimeEntry существует в вашей модели данных.
  2. Убедитесь, что объект TimeEntry связан с классом TimeEntry в вашей модели данных.
  3. Убедитесь, что ваша модель данных действительно загружена вашими тестами.

Обратите внимание, что если вы специально не хотите протестировать проверку сохранения / удаления, вам обычно не нужно добавлять постоянное хранилище к вашему координатору. (И если вы используете постоянное хранилище SQLite в своем приложении, я настоятельно рекомендую использовать его и в ваших тестах; разные типы постоянных хранилищ имеют разные характеристики производительности и поддерживаемые запросы.)

Для обеспечения того, чтобы ваша модель данных была загружен, вы найдете гораздо более плодотворным, я думаю, на самом деле указать URL-адрес для его загрузки, вместо того, чтобы просто надеяться, что вы поместили его в нужное место и что -mergedModelFromBundles: выполнит правильная вещь. Я бы сделал его членом вашего целевого пакета модульного теста, чтобы он был скомпилирован в Ресурсы вашего пакета модульного теста.Таким образом, вы можете просто использовать соответствующий метод NSBundle, чтобы получить путь или URL-адрес к нему.

Наконец, вы захотите поместить настройку вашего стека постоянства Core Data - модель, постоянный координатор хранилища и временный контекст - в метод -setUp в вашем тесте. кейс. Или в методе -setUp базового класса тестового набора, если вы хотите создать более одного класса тестового набора. (То же самое, конечно, касается удаления стека сохраняемости и методов -tearDown .)

7
ответ дан 9 December 2019 в 22:30
поделиться

Я создал образец для среды тестирования основных данных на github. http://github.com/mbrugger/CoreDataDependentProperties/blob/master/LPAutomatedObserving/Tests/ManagedObjectSenTestCase.m

Наследуйте свои тестовые сценарии от ManagedObjectSenTestCase.m / hier и настройте следующие две строки идентификатора пакета своим тестом и имя модели данных

        NSBundle* bundle = [NSBundle bundleWithIdentifier:@"com.yourcompany.ModelTest"];

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

Примеры кода:

-(void) setUp
{
    pool = [[NSAutoreleasePool alloc] init];

    NSMutableSet *allBundles = [[[NSMutableSet alloc] init] autorelease];
    [allBundles addObjectsFromArray:[NSBundle allBundles]];

    NSBundle* bundle = [NSBundle bundleWithIdentifier:@"com.yourcompany.ModelTest"];

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

    NSURL* modelURL = [NSURL URLWithString:path];
    self.model = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] autorelease];

    self.coordinator = [[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model] autorelease];


    LPManagedObjectContext* tempContext = [[[NSManagedObjectContext alloc] init] autorelease];


    [tempContext setPersistentStoreCoordinator:coordinator];
    [tempContext setRetainsRegisteredObjects:YES];

    self.context = tempContext;
}

    -(void) tearDown
{
    NSLog(@"BEGIN: ManagedObjectSenTestCase tearDown");
    @try
    {
        self.context= nil;
        self.model = nil;
        self.coordinator = nil;
        [pool release];
        pool = nil;
    }
    @catch (NSException * e)
    {
        NSLog(@"%@",e);
        NSLog(@"%@", [e callStackSymbols]);
        NSLog(@"context reset failed!");
        @throw(e);

    }
    NSLog(@"END: ManagedObjectSenTestCase tearDown");
}

В этом примере создается основной стек данных, и вы можете вставлять сущности в созданный контекст для тестирования.

4
ответ дан 9 December 2019 в 22:30
поделиться

У меня была такая же проблема. В конце концов я понял, что он не может получить мою модель, но, будучи новичком в разработке iPhone, я не смог придумать, как загрузить ее из URL, как предложил Крис.

Загрузка из пакета, из которого запускались тесты, - вот что помогло мне:

@implementation WhenWorkingWithATiming

Timing *timing;

NSManagedObjectModel *model;
NSPersistentStoreCoordinator *coordinator;
NSManagedObjectContext *context;


- (void) setUp {
    NSArray *bundles = [NSArray arrayWithObject:[NSBundle bundleForClass:[self class]]];
    model = [[NSManagedObjectModel mergedModelFromBundles:bundles] retain];
    NSLog(@"Model: %@", model);

    coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    context = [[NSManagedObjectContext alloc] init];
    [context setPersistentStoreCoordinator:coordinator];

    timing = (Timing *)[NSEntityDescription insertNewObjectForEntityForName:@"Timing" inManagedObjectContext:context];
}

- (void) tearDown {
    [context rollback];
    [context release];
    [coordinator release];
    [model release];
}

- (void) testThatTimingIsInitialised {
    STAssertNotNil(timing, @"should have a timing");
}

@end
0
ответ дан 9 December 2019 в 22:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: