如何在Swift中正确地testing核心数据

目前已经有相当多的学科了,但是我还没有find一个适用于Swift(Xcode 6.2)的解决scheme。

要在Swift中testingCore Data支持的类,我生成了新的托pipe对象上下文,然后将其注入到我的类中。

//Given let testManagedObjectContext = CoreDataTestComposer.setUpInMemoryManagedObjectContext() let testItems = createFixtureData(testManagedObjectContext) as [TestItem] self.itemDateCoordinator.managedObjectContext = testManagedObjectContext //When let data = self.itemDateCoordinator.do() //Then XCTAssert(data.exists) 

问题来自将testing中创build的MOC传递给正在执行的类。 因为实体类是命名空间,所以Core Data不会获取适当的ManagedObject子类,而是返回一个NSManagedObject集合。 循环或对这些对象进行任何操作(在你的类中将是一个testing项目的数组( [TestItem] )。

例如,违规类ItemDateCoordinator会执行这个循环(在从NSFetchRequest提取相关数据NSFetchRequest )“

 for testItem in testItems { testItem.doPart(numberOfDays: 10) } 

会导致:

致命错误:NSArray元素无法匹配Swift数组元素types

此外,我遇到了一个没有太多可靠答案的信息集合:

  • 为了在创build实体时投射实体,我一直在使用Jesse的解决scheme,但是这不适用于更大范围的testing。
  • 一个解决scheme已经发布在涉及到在运行时交换类的另一个问题上,但是这并不适用于我的实体inheritance。
  • 在这种情况下是否有另一种方法来testing你的对象与核心数据? 你怎么做呢?

我正准备将你指向Swift,Core Data和unit testing,但看到你已经find了它。 🙂

这篇文章没有详细说明你的文件应该存在的地方(即在哪个目标中)。 你不应该添加NSManagedObject子类(或任何真正的文件)到两个目标。 我发现这导致了各种难以发现的错误和神秘的错误。

绝对不要这样做。 这是一个可怕的黑客。

相反,使您的类公开并import MyAppTarget您的XCTestCase文件中的XCTestCase 。 更好的是,如我在最近的演讲中提到的,你的模型应该在自己的框架中(一段video将在几周内发布在realm.io上)。 这样做使得您的模型名称空间非常清晰,通常更容易处理。 然后,您需要在访问pipe理对象的任何地方import MyAppModel

我也有一个新的框架, JSQCoreDataKit打算使Core Data更易于在Swift中使用。 此框架的一个关键部分是CoreDataStack ,您可以使用内存存储为您的testing进行初始化。 有示例的演示应用程序,以及备受好评的unit testing。

我相信这是最近更新(iOS 9 / Swift 2.0)在导入的目标上具有可testing关键字,意味着目标的内部类(默认)变成公共的。 从文档:

在这里输入图像说明

所以要添加到上面的jessesquires答案,将@testable附加到您的导入,这应该解决unit testing错误:

 @testable import MyAppTarget