Как насмехаться с UIApplication в Swift?

В настоящее время я использую Quick + Nimble для тестирования модулей в Swift. Я создаю класс Inviter, который отправляет приложения с помощью разных методов.

Мне нужно высмеять UIApplication, чтобы проверить, что мой код вызывает openURL.

Мой код:

import Quick
import Nimble
import OCMock

extension Inviter {
    convenience init(usingMockApplication mockApplication: UIApplication) {
        self.init()
        application = mockApplication
    }
}

class MockUIApplication : UIApplication {
    var application = UIApplication.sharedApplication()

    var openedURL: String?

    override func openURL(url: NSURL) -> Bool {
        openedURL = url.absoluteString
        return true
    }
}

class InviterSpec: QuickSpec {
    override func spec() {

        describe("Inviter") {
            var mockApplication = MockUIApplication()
            var inviter = Inviter(usingMockApplication: mockApplication)

            beforeEach() {
                inviter = Inviter(usingMockApplication: mockApplication)
            }

            context("for WhatsApp invites") {
                beforeEach() {
                    inviter.inviteViaWhatsAppWithMessage("Invite Message.")
                }

                it("should tell the application to open WhatsApp") {
                    expect(mockApplication.openedURL).toNot(beNil())
                }

                it("should send WhatsApp the right message") {
                    let message = mockApplication.openedURL?.lastPathComponent
                    expect(message).to(equal("Invite%Message."))
                }
            }
        }
    }
}

В этом подходе ошибки моего приложения во время выполнения там могут быть понятны только одним UIApplication. Раньше можно было сделать MockUIApplication наследовать от NSObject и передать это. К сожалению, проверка строгого типа Swift также предотвращает это.

Любить любые идеи.

Ответ 1

Вы близки. Используйте протокол для необходимых функций.

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

extension UIApplication: UIApplicationProtocol {}

Затем вам просто нужно использовать протокол вместо класса

extension Inviter {
    convenience init(usingMockApplication mockApplication: UIApplicationProtocol) {
        self.init()
        application = mockApplication
    }
}

Вам нужно будет изменить класс Inviter, чтобы использовать UIApplicationProtocol.