How to mock UIApplication in Swift?

不羁岁月 提交于 2019-12-21 03:39:11

问题


I'm currently using Quick + Nimble for my unit testing in Swift. I'm building an Inviter class that sends app invites via different methods.

I need to mock out UIApplication to verify that my code calls openURL.

My code so far:

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."))
                }
            }
        }
    }
}

In this approach, my app errors at runtime stating there can understandably be only one UIApplication. Previously, one could make MockUIApplication inherit from NSObject, and pass that in. Unfortunately Swift's strict type checking seems to prevent that too.

Would love any ideas.


回答1:


You are close. Use a protocol for the functions you need.

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

extension UIApplication: UIApplicationProtocol {}

Then you just need to use the protocol instead of the class

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

You will need to modify the Inviter class to use UIApplicationProtocol as well.



来源:https://stackoverflow.com/questions/30244157/how-to-mock-uiapplication-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!