Swift 5 中 UNUserNotificationCenter .requestAuthorization 的单元测试

Kra*_*mer 5 tdd swift unusernotificationcenter

我正在 Xcode 和 Swift 中使用测试驱动开发来开发应用程序。

我想添加定时通知警报,以提醒人们返回应用程序执行操作。为此,我需要使用通知中心向我的用户请求授权。

为此,我想在单元测试中编写一个测试,该测试仅在共享 UNUserNotificationCenter 实例调用其 requestAuthorization(options:completionHandler:) 方法时通过。

我尝试过嘲笑 UNUserNotificationCenter:

extension NotificationsExperimentsTests {

    class MockNotificationCentre: UNUserNotificationCenter {

        var didRequestAuthorization = false

        override func requestAuthorization(options: UNAuthorizationOptions = [], completionHandler: @escaping (Bool, Error?) -> Void) {
            didRequestAuthorization = true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试在测试中初始化它时,

func test_requestAuthorization_IsCalled() {

    var mockNotificationCenter = MockNotificationCentre()
}
Run Code Online (Sandbox Code Playgroud)

编译器告诉我:

无法构造“NotificationsExperimentsTests.MockNotificationCentre”,因为它没有可访问的初始值设定项

我不确定下一步要尝试什么,甚至不确定我想做的事情是否可能?

Kra*_*mer 0

这就是我目前所处的位置。感谢之前的回答:

iOS 10 通知单元测试

我的测试课:

import XCTest
import UserNotifications

@testable import NotificationsExperiments

class TestClass: XCTestCase {

    override func setUp() {
     super.setUp()
  }

  func testDoSomething() {
        //Given
        // Class being tested
        let exampleClass = ExampleClass()
        // Create your mock class.
        let mockNotificationCenter = MockNotificationCenter()
        exampleClass.notificationCenter = mockNotificationCenter
    //When
        exampleClass.doSomething()
        //Then
        XCTAssertTrue(mockNotificationCenter.didRequestAuthorization)
  }
}


extension TestClass {

    class MockNotificationCenter: MockUserNotificationCenterProtocol {

        var didRequestAuthorization = false

        func requestAuthorization(options: UNAuthorizationOptions, completionHandler: ((Bool, Error?) -> Void)) {
            didRequestAuthorization = true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的示例类:

import Foundation
import UserNotifications

class ExampleClass {

    #if DEBUG
    var notificationCenter: MockUserNotificationCenterProtocol = UNUserNotificationCenter.current()
    #else
    var notificationCenter = UNUserNotificationCenter.current()
    #endif

    func doSomething() {
        let options: UNAuthorizationOptions = [.alert, .sound, .badge]
        notificationCenter.requestAuthorization(options) {
            (didAllow, error) in
            if !didAllow {
                print("User has declined notifications")
            }
        }
  }
}

#if DEBUG
protocol MockUserNotificationCenterProtocol: class {
    func requestAuthorization(options: UNAuthorizationOptions, completionHandler: ((Bool, Error?) -> Void))

}

extension UNUserNotificationCenter: MockUserNotificationCenterProtocol {
    func requestAuthorization(options: UNAuthorizationOptions, completionHandler: ((Bool, Error?) -> Void)) {
        print("Requested Authorization")
    }
}
#endif
Run Code Online (Sandbox Code Playgroud)

这确实有效,但是有点hacky。在 DEBUG 模式下,它实际上并不发送授权请求,但在发布时会发送授权请求。

任何进一步的贡献将很乐意接受。