How to test your JSON parser

Earlier, we discussed why you should test your JSON parser and how it can save time, catch bugs, and help you build confidence that your code does what you want. But how do you write tests for your JSON parser? And should you make network requests to the API in your tests?

Let’s answer the second question first. Should you write unit tests against your live API?

I don’t think so. Tests written against a live API are brittle and can break for at least two reasons: (1) when the network connection fails or (2) the server is down (which can happen frequently on a development or staging server). These are outside of your control as an iOS developer, so a test failure in a situation like this can’t help you write more correct or more stable code. It’s better to write tests that run locally with sample JSON files so you can avoid these common problems.

So, how do you write tests for your JSON parser?

1. Create a JSON test file

Grab some JSON from your API and save it to a file in your project. Call it response.json, for example.

2. Create a test case

Create a new XCTestCase subclass, then write a test method.

import XCTest
@testable import YourApp

class JSONParserTests: XCTestCase {
    func test_parse() {
    }
}

3. Load the JSON data into the test case

In the test case (test_parse in the example above), load the JSON file and pull the data out of it so you can send it to your parser.

let bundle = NSBundle(forClass: self.dynamicType)
let path = bundle.pathForResource("search-response", ofType: "json")
let data = NSData(contentsOfFile: path!)

You could load the JSON data as a String here, but I prefer turning it into NSData as NSData is what you’ll get when you do this live with NSURLSession or your favorite third-party networking library. This means you can use whatever parse method you’ve defined in your JSON parser so it behaves exactly the same in the unit test as it does live.

4. Call your parser with the JSON data

Call your parser’s parse method, passing in the JSON data and getting the result.

let parser = JSONParser()
let results = parser.parse(data)

5. Make assertions on the result

Write a few XCTAsserts to be sure your result is what you expected.

XCTAssertNotNil(results)

And while this is a decent assertion, it’s probably too weak to verify that your parsing actually worked the way it was supposed to. You probably want to assert that your results object has the data you expected. There’s an entire chapter on Avoiding false confidence with strong assertions in Parsing JSON in Swift.

A few tips:

  • to debug test failures, you can add a Test Failure Breakpoint in the Breakpoint Navigator (⌘7)
  • turn on test coverage to increase your confidence; you can see which code was executed from your unit tests
  • make strong assertions in your tests to avoid false confidence that can come with test coverage

This is an abridged version of the automated testing section from Parsing JSON in Swift; in the book you can learn exactly how to implement each step, with code, screenshots, and more detailed explanations. If you haven’t already, you can grab the free sample below to start building your JSON parser today.