I'm unit testing:
func testParseFakeDeeplinkSuccess() {
let fakeDeeplink = "fakeDeeplink"
let url = touchManager?.handleTouch(["deeplink": fakeDeeplink as NSSecureCoding])
XCTAssertNotNil(url)
}
which will result in "assertionFailure("3DTouch not trackable")"
func handleTouch(_ userInfo: [String: NSSecureCoding]?) -> URL? {
if let shortcut = userInfo?["deeplink"] as? String,
let url = URL(string: shortcut) {
switch shortcut {
default:
assertionFailure("3DTouch not trackable")
}
return url
}
return nil
}
What can I use in my unit tests to tests this properly?
You're hitting the assertion error because that's the branch your code reaches once it's evaluated.
if let shortcut = userInfo?["deeplink"] as? String, let url = URL(string: shortcut) {
// 1. The branch is taken, unwrapped `shortcut`, it's value is "fakeDeeplink"
switch shortcut {
default:
// 2. This is the only branch in the switch, so this case is always executed.
assertionFailure("3DTouch not trackable")
}
}
You might only be seeing a crash in your tests (and not in a production build of your app) because assertionFailure
will have no effect in the default -O
optimization mode used in RELEASE builds.
Tests, by default, will be compiled for DEBUG which uses the -Onone
optimization mode causing assertions to trigger a crash.
If you want to handle an error condition without trapping, you should either return nil
or use a throwing method instead:
struct TouchNotTrackableError: Error { }
func handleTouch(_ userInfo: [String: NSSecureCoding]?) throws -> URL? {
if let shortcut = userInfo?["deeplink"] as? String,
let url = URL(string: shortcut) {
switch shortcut {
default:
throw TouchNotTrackableError()
}
return url
}
return nil
}
Then you can test if the method throws.
func testParseFakeDeeplinkSuccess() {
let fakeDeeplink = "fakeDeeplink"
XCTAssertThrowsError(try touchManager?.handleTouch(["deeplink": fakeDeeplink as NSSecureCoding]))
}