我需要进行模拟UNNotificationResponse,UNNotification以便可以测试我的实现:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Swift.Void)
但是,我无法对这些类进行有效的子类化,因为它们init()被专门标记为unavailable,如果尝试尝试,将导致如下编译错误:
/Path/to/PushClientTests.swift:38:5: Cannot override 'init' which has been marked unavailable
在这里可以采取哪些替代方法?我研究了面向协议的编程路线,但是由于我不控制被调用的API,因此无法修改它以接受要编写的协议。
要做到这一点,请执行以下操作。
在调试时获取对象的真实示例并使用模拟器保存在文件系统中。
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
let encodedObject = NSKeyedArchiver.archivedData(withRootObject: notification)
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/notification.mock"
fileManager.createFile(atPath: path, contents: encodedObject, attributes: nil)
Run Code Online (Sandbox Code Playgroud)
在 Mac 中找到对象并将文件添加到与测试类相同的目标中。
现在在您的测试中取消存档。
let path = Bundle(for: type(of: self)).path(forResource: "notification", ofType: "mock")
let data = FileManager.default.contents(atPath: path ?? "")
let notification = NSKeyedUnarchiver.unarchiveObject(with: data ?? Data()) as? UNNotification
Run Code Online (Sandbox Code Playgroud)
简短的回答:你不能!
相反,分解你的实现
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Swift.Void)
Run Code Online (Sandbox Code Playgroud)
并测试您从那里调用的方法。
测试愉快:)