I'm trying to write a simple extension to XCTestCase so that I don't have to unwrap everything when checking true or false. It's like the normal XCTAssertTrue but takes a Bool?
instead. (XCTAssertEqual takes optionals, so it's odd this one doesn't)
// Currently have this
XCTAssertTrue(thing?.isValid ?? false)
XCTAssertFalse(thing?.isValid ?? true)
// I want this to work on optionals
XCTAssertTrue(thing?.isValid)
XCTAssertFalse(thing?.isValid)
extension XCTestCase {
func XCTAssertTrue(_ expression: Bool?, _ message: String = "", file: StaticString = #file, line: UInt = #line) {
if let unwrapped = expression {
XCTAssertTrue(unwrapped, message, file: file, line: line)
}
XCTFail("It was nil.", file: file, line: line)
}
func XCTAssertFalse(_ expression: Bool?, _ message: String = "", file: StaticString = #file, line: UInt = #line) {
if let unwrapped = expression {
XCTAssertFalse(unwrapped, message, file: file, line: line)
}
XCTFail("It was nil.", file: file, line: line)
}
}
Problem is it calls itself instead of the other XCTAssertTrue, which has different parameters. But why can't it tell the difference?
I can fix it by renaming them to something like XCTAssertOptionalTrue, but I'd like them to have the same name for ease of use. Is this possible?
You can’t write an overload, because this is Objective C under the hood so there are no overloads! Anyway, you're doing way too much work here. The goal apparently is: "Given an Optional Bool, fail if nil, otherwise unwrap and assert true or false". The way to say that is:
XCTAssertTrue(try XCTUnwrap(thing?.isValid)) // or XCTAssertFalse
Observe that this assumes that your test...
function is a throws
function. Well, if it isn't, it should be! The ability of a test...
function to throw is a very important feature; throwing causes the test to fail instantly, which is just what you want.