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.
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.
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]
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
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)
If you take a better look you will see that our completion returns a
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.
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
- 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.