Using XCTUnwrap Instead of Guard in Unit Tests

In 2015, I sang praises for the guard statement to unwrap optional values in tests. But since then, we were blessed with XCUnwrap, which makes things even better in my book. I received a comment on the 2015 piece a couple weeks ago, so I figured I might as well document that things have changed in the meantime!

The original post had this code:

func testAssigningGroup_AddsInverseRelation() {
    insertFile()
    insertGroup()

    guard let file = soleFile() else {
        XCTFail("no file")
        return
    }

    guard let group = soleGroup() else {
        XCTFail("no group")
        return
    }

    // Precondition
    XCTAssertEqual(group.files.count, 0)

    file.group = group

    // Postcondition
    XCTAssertEqual(group.files.count, 1)
    XCTAssert(group.files.anyObject() === file)
}

With the new-ish XCTest helpers, we can write it like this:

func testAssigningGroup_AddsInverseRelation() throws {
    insertFile()
    insertGroup()

    let file = try XCTUnwrap(soleFile())
    let group = try XCTUnwrap(soleGroup())

    // Precondition
    XCTAssertEqual(group.files.count, 0)

    file.group = group

    // Postcondition
    XCTAssertEqual(group.files.count, 1)
    XCTAssert(group.files.anyObject() === file)
}

Back in 2015, tests couldn’t even be marked with throws. So this is a nice way to exit a test case early when a condition isn’t been met.