In my app I wish to assert that notifications have been added in the correct format. I'd normally do this with dependency injection, but I can't think of a way to test the new UNUserNotificationCenter
API.
I started to create a mock object which would capture the notification request:
import Foundation
import UserNotifications
class NotificationCenterMock: UNUserNotificationCenter {
var request: UNNotificationRequest? = nil
override func add(_ request: UNNotificationRequest, withCompletionHandler completionHandler: ((Error?) -> Void)? = nil) {
self.request = request
}
}
However, UNUserNotificationCenter
has no accessible initializers I can't instantiate the mock.
I'm not even sure I can test by adding the notification request and fetching the current notifications, as the tests would need to request permission on the Simulator which would stall the tests. Currently I've refactored the notification logic into a wrapper, so I can at least mock that throughout my application and manually test.
Do I have any better options than manual testing?
You can utilize
UNUserNotificationCenter
, thensetValue
on the returnedsettings
You can create a protocol for the methods you are using, and make an extension on UNUserNotificationCenter to conform to it. This protocol would act as a "bridge" between the original UNUserNotificationCenter implementation and your mock object to replace its method implementations.
Here's an example code I wrote in a playground, and works fine:
Keep in mind that every time you use a new method, you'll have to add it to the protocol, or the compiler will complain.
Hope this helps!
Although it's most probably correct to test that
UNUserNotificationCenter
is called and not to test that it actually works (Apple should test that), you do not need any permissions to schedule and then check the scheduled notifications. Permissions are only needed to actually display the notification (and you definitely not testing that in your unit tests).In my unit tests, I call through to real
UNUserNotificationCenter
implementation and then check the scheduled notifications (UNUserNotificationCenter.current().getPendingNotificationRequests
) and all of this works without any permissions and the tests run extremely quick. This approach is much faster than the one already proposed (in that sense that you need to write less code to be able to test).