Unit Testing — Network request

Nowadays almost every app do a network request to authenticate a user, request an advertising data or to track how users use it. Network request is the way the app uses to update data and show new information without the need of the user update it at App Store or Google Play.

There are some libraries that help developers perform network requests on the iOS world. On this post, we are going to use Alamofire.

A network request returns an error or a success and this success come with a response that can be a JSON string. So we are going to create an enum called Result to handle that.

Our Result is a generic enum that can receive any object in case of success or returns a simple error. This error can be replaced by error(Error) to return an error object, but for this example, we choose to keep it simple.

Result enum

Now let’s create another enum to handle our JSON response which can be an array of objects or a simple one. We are going to use a type alias JsonObject, so don’t forget to declare typealias JsonObject = [String: Any]

JSON enum

This enum will try to parse our JsonObject as an object, if it can’t be parsed we try to parse it as an array and if it still can’t be parsed we return nil.

Network protocol

Now we should isolate our request library in our code this means to create a wrapper around Alamofire so it can be easily replaced if needed. To achieve this we will create a protocol called NetworkRequest with a func request(_ url: URL, method: HTTPMethod, parameters: [String: Any]?, headers: [String: Any]?, completion: @escaping(Result<Json>) -> void)

NetworkRequest protocol

If you take a better look you will see that our completion returns a Result<T> which T is a Json . What this exactly mean? If our request reaches the server our result will be a success and it will return a Json associated. Remember that our Json can contain an object or array.

Now we create our RealNetworkRequest that will implement our NetworkRequest protocol. This is the wrapper that we are going to build around Alamofire.

RealNetworkRequest class

Finally, let’s write some test on our RealNetworkRequest class. To do that we are going to use Mockingjay a library that stubs our HTTP request. Mockingjay stub method takes two closures: one to match the request and other to build the response. We are going to use the everything closure on our tests.

When we call self.stub(everything, json(object)) we are asking Mockingjay to stub every network request and return a json(object) as a response. As we are stub everything we can call any URL e.g. www.google.com.

We test our RealNetworkRequest :

  • in case the server response is a JSON object, array or even an invalid JSON
  • if our server response is an error
  • and if it adds headers and parameters on the request.

Theses tests are an example of a GET method, you can duplicate them for a POST, PUT or any other HTTP method you use in your application just remember to test the expected behavior of your class.

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