在我的应用程序中,我希望断言已以正确的格式添加了通知。我通常会使用依赖注入来实现这一点,但是我想不出一种方法来测试新的UNUserNotificationCenter API。
我开始创建一个模拟对象,它将捕获通知请求:
import Foundation
import UserNotifications
class NotificationCenterMock: UNUserNotificationCenter {
var request: UNNotificationRequest? = nil
override func add(_ request: UNNotificationRequest, withCompletionHandler completionHandler: ((Error?) -> Void)? = nil) {
self.request = request
}
}但是,UNUserNotificationCenter没有可访问的初始化器,我无法实例化模拟。
我甚至不确定我是否能够通过添加通知请求和获取当前通知来进行测试,因为测试需要在模拟器上请求权限,这会使测试陷入停顿。目前,我已经将通知逻辑重构为一个包装器,以便至少可以在整个应用程序中模拟并手动测试。
我有比手工测试更好的选择吗?
发布于 2017-05-12 03:45:11
您可以为正在使用的方法创建协议,并在UNUserNotificationCenter上进行扩展以符合该协议。该协议将充当原始UNUserNotificationCenter实现与模拟对象之间的“桥梁”,以替换其方法实现。
下面是我在操场上编写的示例代码,运行良好:
/* UNUserNotificationCenterProtocol.swift */
// This protocol allows you to use UNUserNotificationCenter, and replace the implementation of its
// methods in you test classes.
protocol UNUserNotificationCenterProtocol: class {
// Declare only the methods that you'll be using.
func add(_ request: UNNotificationRequest,
withCompletionHandler completionHandler: ((Error?) -> Void)?)
}
// The mock class that you'll be using for your test classes. Replace the method contents with your mock
// objects.
class MockNotificationCenter: UNUserNotificationCenterProtocol {
var addRequestExpectation: XCTestExpectation?
func add(_ request: UNNotificationRequest,
withCompletionHandler completionHandler: ((Error?) -> Void)?) {
// Do anything you want here for your tests, fulfill the expectation to pass the test.
addRequestExpectation?.fulfill()
print("Mock center log")
completionHandler?(nil)
}
}
// Must extend UNUserNotificationCenter to conform to this protocol in order to use it in your class.
extension UNUserNotificationCenter: UNUserNotificationCenterProtocol {
// I'm only adding this implementation to show a log message in this example. In order to use the original implementation, don't add it here.
func add(_ request: UNNotificationRequest, withCompletionHandler completionHandler: ((Error?) -> Void)?) {
print("Notification center log")
completionHandler?(nil)
}
}
/* ExampleClass.swift */
class ExampleClass {
// Even though the type is UNUserNotificationCenterProtocol, it will take UNUserNotificationCenter type
// because of the extension above.
var notificationCenter: UNUserNotificationCenterProtocol = UNUserNotificationCenter.current()
func doSomething() {
// Create a request.
let content = UNNotificationContent()
let request = UNNotificationRequest(identifier: "Request",
content: content,
trigger: nil)
notificationCenter.add(request) { (error: Error?) in
// completion handler code
}
}
}
let exampleClass = ExampleClass()
exampleClass.doSomething() // This should log "Notification center log"
EDITED:
/* TestClass.Swift (unit test class) */
class TestClass {
// Class being tested
var exampleClass: ExampleClass!
// Create your mock class.
var mockNotificationCenter = MockNotificationCenter()
func setUp() {
super.setUp()
exampleClass = ExampleClass()
exampleClass.notificationCenter = mockNotificationCenter
}
func testDoSomething() {
mockNotificationCenter.addRequestExpectation = expectation(description: "Add request should've been called")
exampleClass.doSomething()
waitForExpectations(timeout: 1)
}
}
// Once you run the test, the expectation will be called and "Mock Center Log" will be printed请记住,每次使用新方法时,都必须将其添加到协议中,否则编译器会抱怨。
希望这能有所帮助!
发布于 2020-02-04 14:32:13
您可以利用UNUserNotificationCenter,然后在返回的settings上使用setValue
UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { settings in
let status: UNAuthorizationStatus = .authorized
settings.setValue(status.rawValue, forKey: "authorizationStatus")
completionHandler(settings)
})发布于 2022-02-11 06:21:51
我设法使用下面的方法来模拟UNNotificationSettings
let object = UIView()
let data = try! NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: false)
let coder = try! NSKeyedUnarchiver(forReadingFrom: data)
let setting = UNNotificationSettings(coder: coder)
setting?.setValue(UNAuthorizationStatus.notDetermined.rawValue, forKey: "authorizationStatus")https://stackoverflow.com/questions/40862551
复制相似问题