osx - Swift: How to not load AppDelegate during Tests -
i have os x application on startup loads data server , pushes notifications nsusernotificationcenter
. have problem happens during unit tests. found no way yet prevent this. of course stub http loads. in cases want test loading , notifications sent anyway.
what i'm trying make test runs not load appdelegate
fake 1 i'm using tests. found several examples [1] on how uiapplicationmain
, can pass specific appdelegate class name. same not possible nsapplicationmain
[2].
what i've tried following:
removed @nsapplicationmain
appdelegate.swift
, added main.swift
following content:
class fakeappdelegate: nsobject, nsapplicationdelegate { } nsapplication.sharedapplication() nsapp.delegate = fakeappdelegate() nsapplicationmain(process.argc, process.unsafeargv)
this code runs before tests has no effect @ all.
i might have say: appdelegate empty. handle mainmenu.xib stuff made separate view controller actual loading , notification stuff in awakefromnib
.
[1] http://www.mokacoding.com/blog/prevent-unit-tests-from-loading-app-delegate-in-swift/
after days of trying , failing found answer on apple forums:
the problem main.swift file initializing appdelegate before nsapplication had been initialized. apple documentation makes clear lots of other cocoa classes rely on nsapplication , running when initialized. apparently, nsobject , nswindow 2 of them.
so final , working code in main.swift
looks this:
private func istestrun() -> bool { return nsclassfromstring("xctest") != nil } private func runapplication( application: nsapplication = nsapplication.sharedapplication(), delegate: nsobject.type? = nil, bundle: nsbundle? = nil, nibname: string = "mainmenu") { var toplevelobjects: nsarray? // actual initialization of delegate deferred until here: application.delegate = delegate?.init() as? nsapplicationdelegate guard bundle != nil else { application.run() return } if bundle!.loadnibnamed(nibname, owner: application, toplevelobjects: &toplevelobjects ) { application.run() } else { print("an error encountered while starting application.") } } if istestrun() { let mockdelegateclass = nsclassfromstring("mockappdelegate") as? nsobject.type runapplication(delegate: mockdelegateclass) } else { runapplication(delegate: appdelegate.self, bundle: nsbundle.mainbundle()) }
so actual problem before nib being loaded during tests. solution prevents this. loads application mocked application delegate whenever detects test run (by looking xctest
class).
i'm sure have tweak bit more. when start ui testing. moment works.
Comments
Post a Comment