我正在使用自定义实体迁移策略为我的迁移构建一个映射模型,我真的很想为这个迁移构建一些单元测试。当我运行应用程序时,迁移似乎正常工作,但当我通过单元测试运行迁移时,我的 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];
}
我的映射模型指定了一个自定义的 NSEntityMigrationPolicy,它定义了 -createRelationshipsForDestinationInstance:entityMapping:manager:error:
方法,但我的策略从未从单元测试中调用过。当我运行迁移时,模型被修改为新版本——预期的属性显示在正确的位置。
有什么想法可以让我的迁移策略在单元测试中起作用吗?
最佳答案
swift 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")
}
}
关于ios - 我如何对核心数据迁移进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11959447/