2015-05-26 72 views
1

我有稱爲禮品一個管理對象,其具有的屬性夫特單元測試EXC_BAD_ACCESS(碼= 1,地址= 0x8中)

import Foundation 
import CoreData 

class Gift: NSManagedObject { 

    @NSManaged var name: String 
    @NSManaged var price: NSNumber 
    @NSManaged var location: String 

} 

使用單一的單元測試然後我插入一個實體到成功核心數據(無錯誤)。

func testThatWeCanSaveGift() { 
     let entity = NSEntityDescription.entityForName("Gift", inManagedObjectContext: managedObjectContext!) 
     let gift = Gift(entity: entity!, insertIntoManagedObjectContext: managedObjectContext!) 
     gift.name = "Test" 
     gift.price = 10.0 
     gift.location = "London" 

     XCTAssertNotNil(gift, "Unable to create a gift") 

     var error: NSError? = nil 
     managedObjectContext?.save(&error) 

     XCTAssertNil(error, "Failed to save the context with error \(error), \(error?.userInfo)") 

爲了測試這是完全成功的,我使用了一個fetch請求來返回這個數據。

 let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "Gift") 
     var requestError: NSError? = nil 
     if let gifts = managedObjectContext?.executeFetchRequest(fetchRequest, error: &requestError) { 
      let aGift: NSManagedObject = gifts.first as! NSManagedObject 
      //println("Gift name: \(aGift.name)") 
      let string: String? = aGift.valueForKey("name") as? String 
      println("Name: \(string)") 
      var bGift: Gift = aGift as! Gift 
      println("Name: \(bGift.name)") 
      var a = 1 
     } 
    } 

當運行此測試對投射到aGift bGift var bGift: Gift = aGift as! Gift與錯誤EXC_BAD_ACCESS(碼= 1,地址= 0x8中)的線失敗。然而,我確實從aGift中的核心數據獲得了結果,但是作爲NSManagedObject的結果,我只在單元測試中運行代碼時發生這種情況,如果我在應用程序中運行它,它會返回正確的信息並強制轉換它正確。

我在做什麼錯誤的測試?

回答

1

找到了這個網頁上的回答(問題後的第一個答案)Swift and CoreData Casting issues in test vs non-test

我不能投的原因是,NSManagedObject(禮品)完整的類名是MY_PROJECT.Gift,但是當測試運行它試圖將其投射到MY_PROJECT_TESTS.Gift。爲了解決這個問題,我從Core Data Model UI中的實體的類名中刪除了MY_PROJECT,所以它只是讀了Gift。然後,我重新編寫了managedObjectModel代碼。

lazy var managedObjectModel: NSManagedObjectModel = { 
     // The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model. 
     let modelURL = NSBundle.mainBundle().URLForResource("GiftReminder", withExtension: "momd")! 
     let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)! 

     // Check if we are running as test or not 
     let environment = NSProcessInfo.processInfo().environment as! [String: AnyObject] 
     let isTest = (environment["XCInjectBundle"] as? String)?.pathExtension == "xctest" 

     // Create the module name 
     let moduleName = (isTest) ? "GiftReminderTests" : "GiftReminder" 

     // 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 

     return newManagedObjectModel 
    }() 

這將動態檢查我是否正在運行測試,並使用正確的預固定器到類中。

相關問題