Decode JSON with Swift (& test!)
Download, decode and test? O.K. then
It is almost without exception essential that for any application (of a decent size) that you communicate with a backend server. This might be to get pertinent information, upload analytics information or any one of a host of reasons to communicate with another machine.
This article is about taking JSON and decoding it in an App.
Difficulty: Beginner | Easy | Normal | Challenging
API: Application programming interface. A set of accessible tools for building software applications
Backend: the part of a computer system or application that is not directly accessed by the user, typically responsible for storing and manipulating data
Endpoint: An endpoint is a remote computing device that communicates back and forth with a network to which it is connected
Unit testing: Software testing where individual units or components of the software is Software testing where individual units or components of the software is tests
Swift Networking Terminology
URLSession: The class and related classes proved an API for downloading data to and from endpoints indicated by URLs
This is rather similar to mocking
URLSession and making use of dependency injection to do so, and the purpose of this article is to discuss how we can take a resultant JSON String and actually test the response.
The URL that is hit is the https://jsonplaceholder.typicode.com and the example Endpoint. Looking at that website, we expect the following response from the server in the form of a JSON string.
Our Codable class as represented below will give us an object model for the JSON input.
Calling the URL
We can actually make the call through a nicely written function like the following;
Testing the URL Call
We then can test this function, making sure we have our mock and have armed it with appropriate data (within the test)
The three quotation marks “”” produce multi-line String literals, and therefore can be used (given a little luck) to test that the response from the
URLSessionMock() is truly the date we give it (spoiler: It is!)
The test can look something like the following:
Which makes everything seem great. But we aren’t testing the (you know) JSON String decoding.
Setting up the String Decoder
Option 1: Untestable
You could just call
viewDidLoad() (or a button press action), like the following:
This, of course works. But it prints the result to the console, and that isn’t really testable is it (Sir)?
Option 2: Extract out the decoder
So the idea here is to create a decoder function.
To make this reusable I’ll use some generics (but don’t be scared!) The following can be called through a little bit of fun with a do try catch. We tell the function that it will use
UserModel.self to decode the data called
which then calls the following function:
Testing the JSON String decoding
Now in order to check that we have make sure that
UserModel conforms to the
Then we can set up a test that actually tests this (again using the data String from above)
I advise all reading this article to go to the Repo and download the files to have a read through.
In truth, the trickiest part of this is testing, and of course relies on your understanding of mocking. Good luck!
Look, OK you’ve got me. I’ve used my own HTTPManager class in my own projects and I use that to decode my JSON from Endpoints.
However this particular article really breaks down how you can decode JSON, and even test the response (and believe me, you’ll want to test responses without hitting your Endpoint every time; your backend guy might periodically take it down and then….)
The Twitter contact:
Any questions? You can get in touch with me HERE