单元测试 UNUserNotificationCenterDelegate 方法

Posted

技术标签:

【中文标题】单元测试 UNUserNotificationCenterDelegate 方法【英文标题】:Unit Testing UNUserNotificationCenterDelegate Methods 【发布时间】:2020-08-20 20:05:41 【问题描述】:

我想对一些UNUserNotificationCenterDelegate 方法进行单元测试,尤其是userNotificationCenter(_, willPresent:, withCompletionHandler:)

为此,我必须创建一个UNNotification 的实例,但这实际上是不可能的,因为它只有一个initWithCoder 初始化程序。怎么办?

这是我想测试的示例:

func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    willPresent notification: UNNotification,
    withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) 
    completionHandler(.sound)

【问题讨论】:

【参考方案1】:

感谢this README 和private ios headers here,我想出了这个解决方案:

func testUserNotificationCenterDelegate() throws 
    // Create the notification content
    let notificationContent = UNMutableNotificationContent()
    notificationContent.title = "Test"
    notificationContent.userInfo = ["someKey": "someValue"]
    
    // Create a notification request with the content
    let notificationRequest = UNNotificationRequest(identifier: "test", content: notificationContent, trigger: UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false))
    
    // Use private method to create a UNNotification from the request
    let selector = NSSelectorFromString("notificationWithRequest:date:")
    let unmanaged = UNNotification.perform(selector, with: notificationRequest, with: Date())
    let notification = unmanaged?.takeUnretainedValue() as! UNNotification
    
    // Test the method
    let callbackExpectation = XCTestExpectation(description: "Callback")
    pushService.userNotificationCenter(UNUserNotificationCenter.current(), willPresent: notification)  (options) in
        XCTAssertEqual(options, .sound)
        callbackExpectation.fulfill()
    
    wait(for: [callbackExpectation], timeout: 2.0)

在上面的代码中,pushService 是一个符合UNUserNotificationCenterDelegate 协议的类的实例。在我的代码的其他地方,我将该实例设置为中心的委托:UNUserNotificationCenter.current().delegate = pushService

享受吧!

【讨论】:

【参考方案2】:

您可以使用 class_createInstance(UNNotification.classForKeyedArchiver() ...) 并将值转换为 UNNotification

如果您想操作其内容和日期成员,您可以继承 UNNotification 并使用相同的公式“更改类名和演员表”来创建它,然后您覆盖那些打开的成员并返回您想要的任何内容

【讨论】:

以上是关于单元测试 UNUserNotificationCenterDelegate 方法的主要内容,如果未能解决你的问题,请参考以下文章

什么是单元测试?如何做好单元测试?

UNUserNotificationCenter.current().getDeliveredNotifications 只返回一个空数组

测试篇——初探单元测试

单元测试

Java单元测试介绍

Android如何进行单元测试(转)