Unit Testing — Parsing a JSON response

Rodrigo Cavalcante
Cocoa Academy
Published in
3 min readApr 1, 2017

--

Nowadays with a lot of different programming language, we needed to create a way to be able to communicate with all kinds of applications e.g. we can have an iOS app that consumes a node.js application and this same service can also be consumed by an Android or even a voice device like Amazon’s Alexa.

These applications may have different languages, architecture and be created by different companies so how can they exchange data? It can be archive by using XML, YAML, JSON and others. In this post, we are going to see how to parse a JSON to an object class in our project.

But WTH is JSON?

JSON is a common format used to exchange data between computers a.k.a mobile devices, desktop, notebooks, servers, smart watches and more.

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. (from json.org)

When your cellphone request the nearest fast food to a server it probably will return a response in a JSON format like this.

{
"id": 1,
"name": "The nearest fast food",
"address": Main St,
"tags": ["fast", "food"]
}

In our project, we will do a request that will return some user info like username, email, age and a list of access. We expect our server response to be something like:

{
"username": "username",
"email": "em@il",
"age": 26,
"access": ["profile": true, "timeline": true, "friends": true, "dashboard": true]
}

This response should be documented in a swagger file or something like that. Remind that the server can return different responses e.g. a 404 status.

We need to parse our JSON, that means to grab the expected response and turn into objects. There is a lot of libraries that helps you to do that like ObjectMapper or Gloss. Here we are going to build or own parse. Why? Because we can declare our variables with let and non-optional (many of theses libraries you need to declare your properties with var and optional and I don’t like it) and to learn a bit more.

A JSON response is a key value type so we can create a type alias to [String: Any] :

typealias JsonObject = [String: Any]

And then we can create our User and Access struct. Our parse will be done at our init method which will receive a JsonObject aka [String: Any] and parse it to our properties.

User struct
Access struct

After that we can create a test to see if our parser is working (or create the test first if you are using TDD)

Let’s start by testing our Access struct. You probably notice that it has a init that always result in an Access object this mean that if our JSON comes with a missing key it will be parsed to false. To help writing our test we create an extension to Access with a static function that returns a valid JSON.

We wrote 5 tests.

  • One testing the parse of all properties. We call Access(json: validJson) and expect that all our properties will be parsed which means, in our example, all properties be true.
  • Four others will test a missing property. We remove a property from our valid JSON and expect it to be false when our object is created.

If you run all tests, they all should pass

Our User struct is a little bit different because it will not parse invalid properties which mean if our server returns a JSON missing one property our parse will fail and return nil and that is done on purpose.

Let’s build an extension to our User like we did on Access, which will return a valid JSON. And then wrote our tests: one checking if all properties will be parsed and three more removing properties and check if it returned nil.

With theses examples, you can create your own JSON’s parse. The same test structure can be used with other libraries just remember to test the behavior expected e.g. in Access it should parse even if a property is missing and in User, it should return nil.

On my next post I’ll write about testing a network request using MockingJay.

This is a part-2 of a series of posts that shows how to test some stuff on iOS.

--

--