CoreData的insertNewObjectForEntityForName通过单元测试使强制转换为自定义类失败

时间:2015-06-18 14:54:10

标签: swift core-data

我有一个AEUs​​er类,它是NSManagedObject的子类。该类有一个方法可以创建自己的新实例。对于默认目标,正常路由效果很好:

static func newDefaultUser(moc: NSManagedObjectContext) -> AEUser {
    let newUser = NSEntityDescription.insertNewObjectForEntityForName("AEUser", inManagedObjectContext: moc) as! AEUser
    newUser.uid = sDefaultUser // some string constant
    newUser.name = sDefaultUser // some string constant
    return newUser
  }

但是,在执行使用相同函数创建新用户的XCTestCase时,会在运行时发生强制转换错误。我突然不再将新物体投入AEUser了。在默认目标上,一切都运行正常。

现在有趣的是,上述代码的“更长”变体可以完美地用于测试用例。现在演员阵容当然不再需要了。但是上面的代码应该产生完全相同的对象。此外,当使用断点并查看分配给上面的newUser的实际对象时,它似乎应该是一个AEUs​​er对象。

private static func newDefaultUser(moc: NSManagedObjectContext) -> AEUser {
    let entity = NSEntityDescription.entityForName("AEUser", inManagedObjectContext: moc)
    let newUser = AEUser(entity: entity!, insertIntoManagedObjectContext: moc)
    newUser.uid = sDefaultUser // some string constant
    newUser.name = sDefaultUser // some string constant
    return newUser
  }

有人可以解释为什么上面的代码在使用XCTestCase /一个单独的测试目标时不起作用,特别是为什么运行时强制转换失败,尽管上面的代码看起来像第二个变量一样产生了正确类型的对象?

(运行Xcode 6.3.2和iOS 8.3 SDK。)

1 个答案:

答案 0 :(得分:1)

我有类似的问题。进行了一些调试以弄清楚。希望这也适合你。

我认为问题在于演员as! AEUser正在尝试转换为MyAppTests.AEUser,这可能与您的数据模型想要的类不匹配(它可能需要MyApp.AEUser })。您需要使用MyApp.AEUser才能使数据模型引用正确的内容。尝试使用一些断点调试测试并创建AEUser的随机实例,并查看Xcode所说的类型。我打赌你是MyAppTests.AEUser

我的解决方案看起来像这样:我有一个名为Team的实体存在于名为Somersault的应用中。所以,在我的数据模型中(你做这样的课因为this):

enter image description here

然后,确保您的NSManagedObject子类是公共的,以及它的所有属性:

public class Team: NSManagedObject {
   @NSManaged public var name: String
}

然后在测试模块的测试文件中(我的SomersaultTests),引用原始模块:

import Somersault

正常使用您的子类。确保为您的测试模块提供已编译源下的NSManagedObject个文件;您希望测试模块引用原始模块

您现在应该可以像这样直接投射NSManagedObject

let newTeam: Team = NSEntityDescription.insertNewObjectForEntityForName("Team",
    inManagedObjectContext: self.moc!) as! Team
祝你好运。