单元测试应该使用不同的托管对象上下文到主应用程序吗?

时间:2011-09-28 09:08:23

标签: iphone objective-c core-data

所有托管对象上下文代码都位于我的app委托中。我的单元测试类中是否应该有类似的代码?

2 个答案:

答案 0 :(得分:2)

对于单元测试,我专门为测试创建一个内存管理对象上下文。这样就可以在setUp代码中为每个测试销毁和重新创建它,因为它在内存中,保存速度很快。

**编辑**

MOC内容封装在名为ModelLoader的类中。我从我的测试-setUp这样称呼它:

- (void)setUp
{
    [super setUp];

    loader = [[ModelLoader alloc] initWithName: @"MyDocument"];
    NSError* error = nil;
    if (![[loader context] save: &error])
    {
        @throw [NSException exceptionWithName: @"MOCSave" 
                                       reason: [error localizedDescription] 
                                     userInfo: nil];
    }
} 

名称是没有.mom扩展名的数据模型的名称。 save和exception throw只是提供一个完整性检查,确保它是所有初始化属性。顺便说一句,这是GC代码。对于非GC,您需要在-tearDown

中释放加载程序

ModelLoader的相关代码:

-(id) init
{
    return [self initWithName: @"MyDocument"];
}

-(id) initWithName: (NSString*) modelName
{
    self = [super init];
    if (self != nil)
    {
        NSBundle* theBundle = [self bundle];
        NSURL* modelURL = [theBundle URLForResource: modelName 
                                      withExtension: MOM_EXTENSION];
       if (modelURL == nil)
       {
           // log error 
       }
       else 
       {
           model = [[NSManagedObjectModel alloc] initWithContentsOfURL: modelURL];
           if (model == nil)
           { 
               // log error 
           }
       }
    }
    return self;
}

// Create or return the context

-(NSManagedObjectContext*) context
{
    if (context == nil)
    {
        context = [[NSManagedObjectContext alloc] init];
        NSPersistentStoreCoordinator* coordinator
             = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self model]];
        [context setPersistentStoreCoordinator: coordinator];
        NSError* error = nil;
        NSPersistentStore* newStore
            = [coordinator addPersistentStoreWithType: NSInMemoryStoreType 
                                        configuration: nil 
                                                  URL: nil 
                                              options: nil 
                                                 error: &error];
        if (newStore == nil)
        {
            NSLog(@"Failed to create store, reason %@", error);
            context = nil;
        }
    }
    return context;
}

答案 1 :(得分:0)

创建代码的子类,在其中创建NSPersistentStoreCoordinator并使用内存存储覆盖它:

- (NSPersistentStoreCoordinator*) coordinator {
    if (!_coordinator) {
        NSError *error = nil;
        _coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self model]];
        [_coordinator addPersistentStoreWithType:NSInMemoryStoreType 
                                    configuration:nil URL:nil options:nil error:&error];
    }
    return _coordinator;
}

或者在持久性管理器中更改商店的路径:

NSPersistentStore *persistentStore = [_coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];

或者使用相同的类,但缺点是测试需要一个已知的初始状态,这意味着您希望在测试之前重置数据库,删除您在使用应用程序时创建的数据。