Sometimes you might want to create a mock instance of UIApplication to test whether your code calles a certain method correctly - e.g. openUrl(). In Objective-C this was an easy task with OCMock but in Swift it’s a bit tricky.

Trying the usual Swift mocking approach by creating a subclass of the class you want to mock and overriding the methods you want to test fails for UIApplication since the system only allows one UIApplication instance and crashes if you try to instantiate a subclass of it.

Protocols to the rescue!

We can just create a new protocol and let UIApplication conform to it:

protocol UIApplicationProtocol {
  func openURL(url: NSURL) -> Bool
}

extension UIApplication: UIApplicationProtocol {}

Now we can use the protocol instead of UIApplication:

class SampleClass {
  var application: UIApplicationProtocol = UIApplication.sharedApplication()
  func doSomething() {
    application.openURL(NSURL(string: "https://www.google.de"))
  }
}

In the unit test we now just create another implementation of the UIApplicationProtocol to verify that it was called correctly:

class SampleClassTest: XCTestCase {

  let appMock = ApplicationMock()
  let sample = SampleClass()

  func testDoSomething() {
    sample.application = appMock
    application.openURL(NSURL(string: "https://www.google.de"))
	
    XCTAssertEqual(appMock.lastCalledURL!.absoluteString, "https://www.google.de")
  }
	
  class ApplicationMock {
    var lastCalledURL: NSURL?
	
    func openURL(url: NSURL) -> Bool {
      lastCalledURL = url
      return true
    }
  }
}