Swift is great, but all of the Cocoa frameworks are written in Objective-C. This sometimes results in a tension between Swift and the frameworks. Today we’ll talk about a couple of helpers we can add to XCTest to help ease this tension.
Lets say we have a struct in our model layer like this
Now, lets say we want to write a unit test checking that this failable initializer returns us a
Thing when given valid JSON
Unfortunately this gives us a nasty compiler error. In Swift 1.1 we get…
…and in Swift 1.2 we get…
This is because our struct doesn’t conform to the
AnyObject protocol. What we’d like to do is create our own generic helper that can take any optional value, and assert whether it is nil or not. A first pass looks a little something like this
In Swift 1.2 the way
@autoclosure keyword works has changed so the function prototype needs to be…
This little helper looks great, until we run our tests, and discover that our assertion fails at the wrong line in our code. Xcode points out the failure within our helper, rather than at the callsite.
This is suboptimal. However if we take a look at the prototype of
XCTAssertTrue we find a couple of things that look like they might be helpful
Take a look at those
line parameters with default values. Maybe we could pass in our own values for those parameters to tell the test runner where the assertion failure originates from? Apple’s Swift blog comes to our rescue:
Swift has a number of built-in identifiers, including
__FUNCTION__. These expressions can be used anywhere and are expanded by the parser to string or integer literals that correspond to the current location in the source code.
These identifiers expand to the location of the caller when evaluated in a default argument list
This means if we add
line parameters to our helper, with default values of
__LINE__ respectively, like so…
…then our assertion failure happens at the correct point in our code
Huzzah! We can define a similar helper for checking if an optional is nil. For completeness here are the two helpers in Swift 1.1 and Swift 1.2
Hopefully this has helped you understand how to write your own XCTest helpers, and understand the role of identifiers like