New App - NotificationCenter protocols

When starting a new app, I always bring these NotificationCenter protocols into the project.

The idea is that by having these protocols, we can inject the NotificationCenter to the classes/structs instead of using the .default instance.

By doing so, our ability to add unit tests to the code around notifications dramatically increases.

Protocols

Poster

Observer

Publisher

Testing

Then in the testing target, we can create the Mock class of the NotificationCenter that we will inject into our suts.

Example

ViewModel

import Combine

final class ViewModel: ObservableObject {
    @Published var count = 0
    private var notificationHandler: NotificationPublisherProtocol
    private var subscribers: [AnyCancellable] = []

    init(notificationHandler: NotificationPublisherProtocol = NotificationCenter.default) {
        self.notificationHandler = notificationHandler
        addObservers()
    }

    private func addObservers() {
        notificationHandler.publisher(for: .someNotification).sink { [weak self] _ in
            // Every time the notification is published, we increase the count by 1.
            self?.count += 1
        }
        .store(in: &subscribers)
    }
}

extension Notification.Name {
    static let someNotification = Notification.Name("someNotification")
}

ViewModelTests

import XCTest

final class ViewModelTests: XCTestCase {
    private var sut: ViewModel!
    private var notificationCenter: NotificationCenterMock!

    override func setUp() {
        super.setUp()
        notificationCenter = .init()
        sut = .init(notificationHandler: notificationCenter)
    }

    func test_when_notificationIsPosted_countIncreases() {
        // Given
        XCTAssertEqual(sut.count, 0)
        XCTAssertEqual(notificationCenter.postCalls, 0)

        // When
        notificationCenter.post(name: .someNotification)

        // Then
        XCTAssertEqual(sut.count, 1)
        XCTAssertEqual(notificationCenter.postCalls, 1)
        XCTAssertEqual(
            notificationCenter.postedNotifications,
            [.someNotification]
        )
    }
}


New App - NotificationCenter protocols | manu.show
Tags: iOS testing
Share: X (Twitter) LinkedIn