如何对 CloudKit/Core Data 进行单元测试? [英] How to unit test CloudKit/Core Data?

查看:26
本文介绍了如何对 CloudKit/Core Data 进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在弄清楚如何为 CloudKit 和 Core Data 制作模拟/存根时遇到了一些麻烦.

I'm having some trouble figuring out how to make mocks/stubs for CloudKit and Core Data.

通过注入符合我编写的协议的数据库,我在 CloudKit 服务层上取得了一些进展,该协议基本上覆盖了 CKDatabase 函数.

I have made some progress with my CloudKit service layer by injecting a database which conforms to a protocol I've written that essentially overrides CKDatabase functions.

/// 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 注入到我的服务中,或者我可以创建一个符合相同协议的模拟类并注入我的 MockCKDatabasecode> 进入我的单元测试服务实例.这适用于所有功能除了add(operation) 函数.我不确定如何将 CKQueryOperation 添加到我的 MockCKDatabase 以触发其完成块.

With this, I can inject the real CKContainer.default().publicCloudDatabase into my service or I can create a mock class that conforms to the same protocol and inject my MockCKDatabase into my unit tests service instance. This works for all the functionality except the add(operation) function. I'm not sure how to get a CKQueryOperation added to my MockCKDatabase to have its completion blocks triggered.

对于核心数据部分,我使用新的 NSPersistentCloudKitContainer 来同步用户的私有数据库(同时使用我的 CloudKit 服务查询我的公共数据库).我找到了一个关于创建核心的优秀博客允许您在设置堆栈时注入存储类型的数据堆栈,以便您可以在生产中使用 NSSQLiteStoreType 和在测试中使用 NSInMemoryStoreType.

For the Core Data portion, I am using the new NSPersistentCloudKitContainer to sync the user's private database (while using my CloudKit service to make queries to my public database). I found an excellent blog about creating a Core Data stack that allows you to inject the store type when setting up the stack so that you can use NSSQLiteStoreType in production and NSInMemoryStoreType in testing.

但是,当我尝试使用内存解决方案时,出现以下错误:

However, when I try to use the in-memory solution I get the following error:

"NSLocalizedFailureReason" : "CloudKit 集成仅支持 SQLite 存储."

"NSLocalizedFailureReason" : "CloudKit integration is only supported for SQLite stores."

是否有更好的解决方案来测试 CloudKit/Core Data?我真的很想彻底测试我的服务层.

Is there some better solution to test CloudKit/Core Data? I would really like to have my service layers thoroughly tested.

推荐答案

我不确定如何将 CKQueryOperation 添加到我的 MockCKDatabase 以触发其完成块.

I'm not sure how to get a CKQueryOperation added to my MockCKDatabase to have its completion blocks triggered.

您必须自己实现操作的行为.为您使用的每个操作子类编写带有 caseswitch 语句.在每种情况下查看操作的属性,执行请求的行为,然后使用适当的结果或错误调用回调.

You have to implement the operation's behavior yourself. Write a switch statement with a case for each operation subclass that you use. In each case look at the properties of the operation, do the requested behavior, and then call the callback with the appropriate result or error.

我现在正在做这件事,但遇到了障碍.处理 CKFetchRecordZoneChangesOperation 涉及返回一个 CKServerChangeToken 实例,但无法创建这样的对象,因为它没有公共构造函数.并且在获取记录时,无法创建具有指定日期和 changeTags 的 CKRecords.

I'm halfway through doing this right now, but running into roadblocks. Handling CKFetchRecordZoneChangesOperation involves returning a CKServerChangeToken instance, but there's no way to create such an object since it has no public constructor. And when fetching records, there's no way to create CKRecords with specified dates and changeTags.

这篇关于如何对 CloudKit/Core Data 进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆