2012-08-14 10 views
14

私はカスタムエンティティ移行ポリシーを使って移行のためのマッピングモデルを構築しています。この移行のためにいくつかの単体テストを作成したいと思います。アプリケーションを実行すると、マイグレーションが正しく動作するように見えますが、ユニットテストでマイグレーションを実行すると、NSEntityMigrationPolicyサブクラスメソッドはまったく呼び出されません。コアデータの移行を単体テストする方法を教えてください。

私はXcodeの組み込みOCUnitフレームワークを使用しています。

私のテストコード:

- (void)test1to2Migration_appIdentifierMoved { 
    [self createVersion1Store]; 

    // TODO Perform migration 
    NSManagedObjectModel *version1Model = [self version1Model]; 
    NSManagedObjectModel *version2Model = [self version2Model]; 

    NSError *error = nil; 
    NSMappingModel *mappingModel = [NSMappingModel 
     inferredMappingModelForSourceModel:version1Model 
     destinationModel:version2Model error:&error]; 
    STAssertNotNil(mappingModel, @"Error finding mapping model: %@", error); 

    NSMigrationManager *migrationManager = 
     [[[NSMigrationManager alloc] 
     initWithSourceModel:version1Model 
     destinationModel:version2Model] 
     autorelease]; 

    BOOL migrationSucceeded = 
     [migrationManager migrateStoreFromURL:self.version1StoreURL 
      type:NSSQLiteStoreType 
      options:nil 
      withMappingModel:mappingModel 
      toDestinationURL:self.version2StoreURL 
      destinationType:NSSQLiteStoreType 
      destinationOptions:nil 
      error:&error]; 
    STAssertTrue(migrationSucceeded, @"Error migrating store: %@", error); 

    // TODO Verify appIdentifier is moved from Project to its Tests 

    [self deleteTempStores]; 
} 

マイマッピングモデルは-createRelationshipsForDestinationInstance:entityMapping:manager:error:メソッドを定義するカスタムNSEntityMigrationPolicyを指定しますが、私のポリシーは、ユニットテストから呼び出されることはありません。移行を実行すると、モデルが新しいバージョンに変更されます。期待される属性が適切な場所に表示されます。

マイグレーションポリシーをユニットテストで使用するにはどうすればよいですか?

答えて

4

問題は、私が正しく、その後

NSMappingModel *mappingModel = [NSMappingModel 
    mappingModelFromBundles:@[[NSBundle bundleForClass:[MyTestClass class]]] 
    forSourceModel:version1Model destinationModel:version2Model]; 

にテスト機能を、それを変更した場合はライン

NSMappingModel *mappingModel = [NSMappingModel 
    inferredMappingModelForSourceModel:version1Model 
    destinationModel:version2Model error:&error]; 

であることが判明しました。

2

スウィフト3

置き換え変数MODELNAMEとあなたのモデルのためのmodelNameVersionFormatStringファイル名

import XCTest 
import CoreData 

class RCCoreDataMigrationTests: XCTestCase { 

    private let storeType = NSSQLiteStoreType 
    private let modelName = "Model" 
    private let modelNameVersionFormatString = "Model-%@" 

    private func storeURL(_ version: String) -> URL? { 
     let storeURL = URL(fileURLWithPath: "\(NSTemporaryDirectory())\(version).sqlite") 
     return storeURL 
    } 

    private func createObjectModel(_ version: String) -> NSManagedObjectModel? { 
     let bundle = Bundle.main 
     let managedObjectModelURL = bundle.url(forResource: modelName, withExtension: "momd") 
     let managedObjectModelURLBundle = Bundle(url: managedObjectModelURL!) 
     let modelVersionName = String(format: modelNameVersionFormatString, version) 
     let managedObjectModelVersionURL = managedObjectModelURLBundle!.url(forResource: modelVersionName, withExtension: "mom") 
     return NSManagedObjectModel(contentsOf: managedObjectModelVersionURL!) 
    } 

    private func createStore(_ version: String) -> NSPersistentStoreCoordinator { 
     let model = createObjectModel(version) 
     let storeCoordinator = NSPersistentStoreCoordinator(managedObjectModel: model!) 
     try! storeCoordinator.addPersistentStore(ofType: storeType, 
               configurationName: nil, 
               at: storeURL(version), 
               options: nil) 
     return storeCoordinator 
    } 

    private func migrateStore(fromVersionMOM: String, toVersionMOM: String) { 
     let store = createStore(fromVersionMOM) 
     let nextVersionObjectModel = createObjectModel(toVersionMOM)! 
     let mappingModel = NSMappingModel(from: [Bundle.main], forSourceModel: store.managedObjectModel, destinationModel: nextVersionObjectModel)! 
     let migrationManager = NSMigrationManager(sourceModel: store.managedObjectModel, destinationModel: nextVersionObjectModel) 
     do { 
      try migrationManager.migrateStore(from: store.persistentStores.first!.url!, 
               sourceType: storeType, 
               options: nil, 
               with: mappingModel, 
               toDestinationURL: storeURL(toVersionMOM)!, 
               destinationType: NSSQLiteStoreType, 
               destinationOptions: nil) 
     } catch { 
      print("Error: \(error)") 
      XCTAssertNil(error) 
     } 
     try! FileManager.default.removeItem(at: storeURL(toVersionMOM)!) 
     try! FileManager.default.removeItem(at: storeURL(fromVersionMOM)!) 
    } 

    func testMigratingStores() { 
     migrateStore(fromVersionMOM: "1486", toVersionMOM: "1487") 
    } 
} 
関連する問題