Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 2.0 Unit Testing for NSCoding

I am going to try and use the new testing features in Xcode 7 (code coverage) and Swift 2.0.

Using code coverage, I see that I am not testing my NSCoding methods.

enter image description here

For a trivial example of saving a few details, such as:

required init(coder aDecoder: NSCoder) {
    name = aDecoder.decodeObjectForKey("name") as! String
    time = aDecoder.decodeIntegerForKey("time")
}

func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeInteger(time, forKey: "time")
    aCoder.encodeObject(name, forKey: "name")
}

How do I go about testing these methods in an XCTest class.

like image 875
DogCoffee Avatar asked Aug 15 '15 23:08

DogCoffee


2 Answers

Walking away from a problem always helps.

func testDecoder() {

    let path = NSTemporaryDirectory() as NSString
    let locToSave = path.stringByAppendingPathComponent("teststasks")

    let newTask = Task(name: "savename", time: "10")

    // save tasks
    NSKeyedArchiver.archiveRootObject([newTask], toFile: locToSave)

    // load tasks
    let data = NSKeyedUnarchiver.unarchiveObjectWithFile(locToSave) as? [Task]

    XCTAssertNotNil(data)
    XCTAssertEqual(data!.count, 1)
    XCTAssertEqual(data!.first?.name, "savename")
    XCTAssertEqual(data!.first?.time, 10)
}
like image 192
DogCoffee Avatar answered Sep 21 '22 01:09

DogCoffee


Improving @DogCoffee answer a bit, in case you don't want to create actual files during tests and just instead encode and decode to a simple Data memory based buffer:

func testDecoder() throws {
    let savedTask = Task(name: "savename", time: "10")

    let encodedData = try NSKeyedArchiver.archivedData(withRootObject: [savedTask], requiringSecureCoding: false)
    let loadedTasks = try XCTUnwrap(try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(encodedData) as? [Task])

    XCTAssertEqual(loadedTasks.count, 1)
    let loadedTaks = loadedTasks.first! 

    XCTAssertEqual(loadedTask.name, "savename")
    XCTAssertEqual(loadedTask.time, 10)
}

This also uses the newer XCTUnwrap(expression) API to assert that an expression is not nil, and then return the unwrapped value.

like image 20
Paulo Mattos Avatar answered Sep 22 '22 01:09

Paulo Mattos