Swift using and testing notifications
I think everyone would agree the notification pattern within objective-c is a great way to decouple views from services.
Posting a notification in swift is similar to the objective-c implement just with the new syntax.
NSNotificationCenter.defaultCenter.postNotification(name: “notificationName”, object: nil)
When adding an observer to the Notification Center in swift. The class that is being set as the observer must be an objective-c type (Derive from NSObject). When the class isn’t an objective-c type, when the notification selector fires and exception is thrown crashing the app.
NSNotificationCenter.defaultCenter.addObserver(selector: “methodToInvoke:”, name: “notificationName”)
fund methodToInvoke(notification: NSNotification) {
//Do Stuff
}
Testing NSNotificationCenter
Currently this is no native mocking framework for swift meaning the only viable way to mock object is using hand rolled mocks.
In the test target create a new swift class called: MockNSNotificationCenter. In the new class, subclass NSNotificationCenter then override the methods your test is expecting to call as described below:
class MockNSNotificationCenter: NSNotificationCenter {
var lastPostedNotificationName:String?
override func addObserver(observer: AnyObject, selector aSelector: Selector, name aName: String?, object anObject: AnyObject?) {
override func postNotificationName(aName: String?, object anObject: AnyObject?) {
lastPostedNotificationName = aName!
Then in your real class you use lazy instantiation to allow the mock notification center to be injected.
lazy var notificationCenter: NSNotificationCenter = {
return NSNotificationCenter.defaultCenter()
func someMethodPostNotification() {
notificationCenter.postNotification(name: “notificationName”, object: nil)
In your test class you can assert that a notification is posted when a method is called
class RealClassTests: XCTestCase {
let mockNotification = MockNSNotificationCenter()
func testNotification() {
sut.notificationCenter = mockNotification
sut.someMethodPostNotification()
XCTAssertEqual(mockNotification.postCount, 1, "a notification should be posted")