如何对 CloudKit/Core Data 进行单元测试?
Posted
技术标签:
【中文标题】如何对 CloudKit/Core Data 进行单元测试?【英文标题】:How to unit test CloudKit/Core Data? 【发布时间】:2020-04-16 01:04:38 【问题描述】:我在弄清楚如何为 CloudKit 和 Core Data 制作模拟/存根时遇到了一些麻烦。
我在 CloudKit 服务层方面取得了一些进展,方法是注入一个符合我编写的协议的数据库,该协议基本上覆盖了CKDatabase
函数。
/// A protocol to allow mocking a CKDatabase.
protocol CKDatabaseProtocol
func add(_ operation: CKDatabaseOperation)
func delete(withRecordID recordID: CKRecord.ID, completionHandler: @escaping (CKRecord.ID?, Error?) -> Void)
func fetch(withRecordID recordID: CKRecord.ID, completionHandler: @escaping (CKRecord?, Error?) -> Void)
func perform(_ query: CKQuery, inZoneWith zoneID: CKRecordZone.ID?, completionHandler: @escaping ([CKRecord]?, Error?) -> Void)
func save(_ record: CKRecord, completionHandler: @escaping (CKRecord?, Error?) -> Void)
extension CKDatabase: CKDatabaseProtocol
有了这个,我可以将真正的CKContainer.default().publicCloudDatabase
注入到我的服务中,或者我可以创建一个符合相同协议的模拟类并将我的MockCKDatabase
注入到我的单元测试服务实例中。这适用于所有功能除了add(operation)
功能。我不确定如何将CKQueryOperation
添加到我的MockCKDatabase
以触发其完成块。
对于核心数据部分,我使用新的NSPersistentCloudKitContainer
来同步用户的私有数据库(同时使用我的 CloudKit 服务对我的公共数据库进行查询)。我发现了一个很好的 blog 创建一个核心数据堆栈,它允许您在设置堆栈时注入存储类型,以便您可以在生产中使用 NSSQLiteStoreType
并在测试中使用 NSInMemoryStoreType
。
但是,当我尝试使用内存解决方案时,我收到以下错误:
"NSLocalizedFailureReason" : "CloudKit 集成仅支持 SQLite 存储。"
是否有更好的解决方案来测试 CloudKit/Core Data?我真的很想彻底测试我的服务层。
【问题讨论】:
【参考方案1】:我不确定如何将 CKQueryOperation 添加到我的 MockCKDatabase 以触发其完成块。
您必须自己实现操作的行为。为您使用的每个操作子类编写带有case
的switch
语句。在每种情况下查看操作的属性,执行请求的行为,然后使用适当的结果或错误调用回调。
我现在正在执行此操作,但遇到了障碍。处理CKFetchRecordZoneChangesOperation
涉及返回一个CKServerChangeToken
实例,但由于它没有公共构造函数,因此无法创建这样的对象。而且在获取记录时,无法创建具有指定日期和 changeTags 的 CKRecords。
【讨论】:
以上是关于如何对 CloudKit/Core Data 进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Core Data 对数据进行制表 - 如何有效过滤?
如何在 GROUP BY 之前对 Core Data 记录进行排序?
如何对 Stack Exchange Data Explorer (SEDE) 结果进行分页?