如何让单元测试访问核心数据模型

Posted

技术标签:

【中文标题】如何让单元测试访问核心数据模型【英文标题】:How to give unit tests access to Core Data models 【发布时间】:2017-02-01 16:59:57 【问题描述】:

假设我在我的项目中创建了 Core Data 模型。我有其他类的方法可以接收这些模型并根据它们的属性执行一些功能。如何对这些类进行单元测试?

对于普通的 Swift 文件,我在 Xcode 中选择它们并勾选一个框,使这些文件中定义的任何类对项目的单元测试部分可见。我的问题本质上是,如何使我的核心数据模型也对测试可见?

请注意,我不想在 Core Data 堆栈上执行任何操作,我只想能够创建模型的实例并将其传递给方法。

【问题讨论】:

【参考方案1】:

由于 CoreData 使用托管对象,任何 NSManagedObject 的子类在功能上都是毫无价值的,除非附加到上下文中。

测试的一个技巧是在内存中创建一个 NSManagedObjectContext 并使用该上下文创建对象测试。 Outlined Here

这是在内存中创建上下文的代码:

func setUpInMemoryManagedObjectContext() -> NSManagedObjectContext 
    let managedObjectModel = NSManagedObjectModel.mergedModelFromBundles([NSBundle.mainBundle()])!

    let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)

    do 
        try persistentStoreCoordinator.addPersistentStoreWithType(NSInMemoryStoreType, configuration: nil, URL: nil, options: nil)
     catch 
        print("Adding in-memory persistent store failed")
    

    let managedObjectContext = NSManagedObjectContext()
    managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator

    return managedObjectContext

【讨论】:

【参考方案2】:

更新:访问器实现是在运行时生成的,但如果模型对象未与 NSManagedObjectContext 关联,它们将不可用。所以 PEEJWEEJ 的答案是要走的路。

如果我没记错的话,你的实体的 Objective-C 类(特别是它们的属性访问器)是在运行时生成的,当它们被使用时。所以我希望您需要使用适当的NSEntityDescription 调用NSManagedObjects 初始化程序:

NSManagedObject(entity: entityDescription, insertInto: nil)

您可以通过使用NSManagedObjectModel 加载对象模型并使用例如该对象的entitiesByName 属性。

如果您为 NSManagedObject 子类使用自定义代码(例如使用 mogenerator 生成),我会假设需要应用相同的过程 - 使生成的代码对您的测试可见并使用 MyModelClass(entity: entityDescription, insertInto: nil) 初始化程序。

【讨论】:

你错了:)你自己创建类(或生成它们)。问题是它们是 ManagedObjects,因此除非正确附加到 NSManagedObjectContext,否则类的属性不可用 在 MOC 之外使用这些属性会发生什么? 程序会崩溃或者抛出异常。

以上是关于如何让单元测试访问核心数据模型的主要内容,如果未能解决你的问题,请参考以下文章

如何快速测试框架中使用的核心数据模型

在单元测试中构建核心数据堆栈时出错

如何使用 MVVM 架构编写核心位置并执行单元测试?

用于单元测试的内存存储中的 iOS 10 核心数据

如何在单元测试中访问 Dart 类

如何对 WCF 服务进行单元测试?