2015-07-01 49 views
1

這是我XCTestCase類的開始:與例如單元測試的核心數據

var moc: NSManagedObjectContext! 

    override func setUp() { 
     super.setUp() 

     moc = self.setUpInMemoryManagedObjectContext() 
     self.fillManagedObjectContextWithExampleData(moc) 
    } 

    func setUpInMemoryManagedObjectContext() -> NSManagedObjectContext { 

     let modelName = "ProjectApp" 
     let modelURL = NSBundle.mainBundle().URLForResource(modelName, withExtension:"momd")! 
     let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)! 

     let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel) 
     persistentStoreCoordinator.addPersistentStoreWithType(NSInMemoryStoreType, configuration: nil, URL: nil, options: nil, error: nil) 

     let managedObjectContext = NSManagedObjectContext() 
     managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator 

     return managedObjectContext 
    } 

    func fillManagedObjectContextWithExampleData(context: NSManagedObjectContext) { 
     // var firstSC = NSEntityDescription..insertNewObjectForEntityForName("StaticContent", inManagedObjectContext: context) as! StaticContent 
     var staticContentEntity = NSEntityDescription.entityForName("StaticContent", inManagedObjectContext: context)! 

     var firstSC = StaticContent(entity: staticContentEntity, insertIntoManagedObjectContext: context) 
     firstSC.name = "First Name" 

     var secondSC = StaticContent(entity: staticContentEntity, insertIntoManagedObjectContext: context) 
     secondSC.name = "Second Name" 

     var error: NSError? = nil 

     if context.save(&error) { 
      return 
     } 
    } 

我只是想創建managedObjectContext(在內存中,只是用於測試),並帶有示例數據填充它。所以我可以使用:

managedObjectContext.executeFetchRequest(fetchRequest, error: nil) as! [StaticContent] 

在我的單元測試。它執行,但是當我調用函數,該函數[StaticContent]我得到了一個錯誤:

fatal error: NSArray element failed to match the Swift Array Element type 

那麼,什麼是問題呢?我所稱的功能工作正常。當我在我的應用程序中使用它而不是在單元測試中時,我沒有問題。那麼我做錯了什麼?

+0

你能後,你所得到的是錯誤的代碼? – e1985

+1

順便說一句,這可能與實體的managedObjectClassName在您的測試目標中有所不同:如果您的管理對象子類包含在您的測試目標中,它的類名將是YourTestTarget.StaticContent ...它可以用此解決解決方法:https://gist.github.com/efa85/d82cc8fb0358e970e1e4 – e1985

+0

謝謝,我發現在另一個stackoverflow問題類似的代碼。我正在尋找解決方案的小時,然後我發佈我的問題後,我發現它。 –

回答

1

我真的不喜歡回答我的問題,但我找到了答案,我想幫助其他人。我發現了一部分代碼,根據它們運行的​​目標來改變實體類名。所以,我已經添加幾行代碼,我創建NSManagedObjectModel,它可以幫助:

// Create the module name 
    let moduleName = "ProjectAppTests" 

    // Create a new managed object model with updated entity class names 
    var newEntities = [] as [NSEntityDescription] 
    for (_, entity) in enumerate(managedObjectModel.entities) { 
     let newEntity = entity.copy() as! NSEntityDescription 
     newEntity.managedObjectClassName = "\(moduleName).\(entity.name)" 
     newEntities.append(newEntity) 
    } 
    let newManagedObjectModel = NSManagedObjectModel() 
    newManagedObjectModel.entities = newEntities 

    let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: newManagedObjectModel) 

不知道爲什麼它是使用Swift在覈心數據類名字這麼複雜。但它有幫助,現在正在工作。

+0

這看起來與http://stackoverflow.com/a/26796626/1187415中提出的解決方案非常相似。 –

+0

在閱讀完這個問題之後,我認爲最好的解決方案是使用@objc(YourClass),如Christer的回答中所建議的 – e1985

+0

我試圖使用@objc(YourClass),但仍然遇到問題。 –

0
在SWIFT 3.0

func setUpInMemoryManagedObjectContext() -> NSManagedObjectContext { 
     let moduleName = "Model" 
     do { 
      let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) 
      let modelURL = Bundle.main.url(forResource: moduleName, withExtension:"momd") 
      let newObjectModel = NSManagedObjectModel.init(contentsOf: modelURL!) 
      let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel : newObjectModel!) 
      try persistentStoreCoordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil) 

      managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator 
      return managedObjectContext 
     } catch let error as NSError { 
      logErr(error.localizedDescription) 
      XCTFail() 
     } 
     XCTFail("failed to created mocked coreData (inMemroy)") 
     return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) 
    } 
func fillManagedObjectContextWithExampleData(context: NSManagedObjectContext) { 
//lets assume you got some Food POJO class 
    do { 
     let foodJson: NSDictionary = ["id" : "1" , "foodId" : "1" , "displayName": "Pizza"] 
     let firstFood = try Food.createOrUpdate(dict: foodJson, inManagedObjectContext: context) 
     try context.save() 
     return 
    } catch let error as NSError { 
     logErr(error.localizedDescription) 
    } 
}