问题
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