Monday, 27 May 2019

How to Unit Test locale-specific UNUserNotifications

I have just added local notifications to my app. These notifications are supposed to fire only if the app Locale's regionCode (i.e. Locale.current.regionCode) is "US" or "CA". I am not interested in the locale's language.

My questions:

1. How can a Locale be injected into the test (see testSuccessfulNotificationDelivery())?

2. If we take locale out of the test suite, the test only works partially. The assertion fails saying that only 1 notification has been delivered instead of 2. I have a feeling this has to do with the asynchronous nature of my code. Can you help me identify the culprit, and provide a suitable workaround?

LocalNotificationTests.swift:

import XCTest
import UserNotifications
@testable import App

class LocalNotificationTests: XCTestCase {

    var notification1: LocalNotification!
    var notification2: LocalNotification!
    var notificationManager: NotificationManager!

    override func setUp() {
        super.setUp()

        // LocalNotification is a custom model for local notifications
        notification1 = LocalNotification(toTriggerInSeconds: 5)
        notification2 = LocalNotification(toTriggerInSeconds: 6)

        // This object manages LocalNotifications 
        // by building them into UNUserNotifications
        // and then scheduling them using UNUserNotificationCenter. 
        notificationManager = NotificationManager()
    }

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

    func testSuccessfulNotificationDelivery()() {

        // setup locale and use it for testing, somehow
        let 🇺🇸 = Locale(identifier: "en_US")

        // The answer to (1) would go here. (Inject Locale into the test, somehow?)


        notificationManager.schedule(notification1, notification2)

        let expectation = self.expectation(description: "successful notification delivery")

        var deliveredNotifications: [UNNotification]?

        // the answer to (2) is related to this asynchronous code
        UNUserNotificationCenter.current().getDeliveredNotifications {
            deliveredNotifications = $0
            expectation.fulfill()
        }

        waitForExpectations(timeout: 10, handler: nil)

        // Fails. Only 1 notification is delivered.
        XCTAssertEqual(deliveredNotifications?.count, 2) 
    }
}

The following assumption should be made:

  • notificationManager works as expected. Outside of this test suite, I have seen that notificationManager can schedule and deliver as many notifications as I want.


from How to Unit Test locale-specific UNUserNotifications

No comments:

Post a Comment