title: How to Test APIs in Swift 4?
body: <p>I am new to Unit Testing. I have tested a lot of functions and I understood the concept, now I want to check the APIs. Is it possible? I guess so. This is the API:</p>
  
  <pre><code>func sendRequest(path: String, params: Dictionary&lt;String, Any&gt;, showSpinner: Bool, completionHandler: @escaping (JSON, Error?) -&gt; Void) {
      if Constants.IS_SIMULATOR {
          print("Path: \(path)")
          print("Params: \(params)")
      }
  
      if Constants.APP_DEL.reachability?.connection == .none {
          completionHandler(JSON.null, NSError(domain: "No internet", code: 4, userInfo: nil))
          return
      }
  
      UIApplication.shared.isNetworkActivityIndicatorVisible = true
  
      if showSpinner {
          HUD.show(.labeledProgress(title: "Loading...", subtitle: "Please wait"))
      }
  
      if let jsonData = try? JSONSerialization.data(withJSONObject: params, options: .prettyPrinted) {
  
          let url = NSURL(string: String(format: "%@%@", Constants.TEST_URL, path))!
          let request = NSMutableURLRequest(url: url as URL)
          request.httpMethod = "POST"
          request.httpBody = jsonData
          request.timeoutInterval = 120
  
          let task = URLSession.shared.dataTask(with: request as URLRequest){ data, response, error in
              DispatchQueue.main.async {
                  if error != nil {
                      print(" ........ \(String(describing: error?.localizedDescription))")
                      UIApplication.shared.isNetworkActivityIndicatorVisible = false
  
                      if showSpinner {
                          HUD.flash(.labeledError(title: "Server issue", subtitle: "Invalid response"), delay: 2.0)
                      }
  
                      completionHandler(JSON.null, NSError(domain: "Invalid response", code: 420, userInfo: nil))
                      return
                  }
  
  
                  if (data?.isGzipped)! {
                      let decompressedData: Data = try! data!.gunzipped()
                      var json: JSON = JSON.null
                      do {
                          json = try JSON(data: decompressedData)
                      }
                      catch {
                          print(error)
                      }
  
                      if Constants.IS_SIMULATOR {
                          print("Response: \(json)")
                      }
  
                      UIApplication.shared.isNetworkActivityIndicatorVisible = false
  
  
                      if json["status"].int == 200 {
                          if showSpinner {
                              HUD.flash(.success, delay: 0.5)
                          }
                          completionHandler(json["data"], nil)
                      }
                      else if json["status"].int == 202 {
                          if showSpinner {
                              HUD.hide()
                          }
                          completionHandler(JSON.null, NSError(domain: json["message"].string!, code: json["status"].int!, userInfo: nil))
                      }
                      else if json["status"].int == 310 {
                          if showSpinner {
                              HUD.hide()
                          }
                          completionHandler(json["data"], nil)
                      }
                      else if json["status"].int == 403 {
                          if showSpinner {
                              HUD.hide()
                          }
  
                          GeneralHelper.sharedInstance.displayAlertMessage(titleStr: "Session expired", messageStr: "Kindly login again.")
  
                          DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
  
                              let domain = Bundle.main.bundleIdentifier!
                              UserDefaults.standard.removePersistentDomain(forName: domain)
                              UserDefaults.standard.synchronize()
                              Constants.APP_DEL.navC?.popToRootViewController(animated: false)
                          })
                          completionHandler(JSON.null, NSError(domain: json["message"].string!, code: json["status"].int!, userInfo: nil))
                      }
                      else {
                          if showSpinner {
                              HUD.flash(.labeledError(title: "", subtitle: json["message"].string!), delay: 2.0)
                          }
                          completionHandler(JSON.null, NSError(domain: json["message"].string!, code: json["status"].int!, userInfo: nil))
                      }
                  }
                  else {
                      let backToString = String(data: data!, encoding: String.Encoding.utf8) as String?
                      if Constants.IS_SIMULATOR {
                          print("Invalid response: \(String(describing: backToString))")
                      }
                      UIApplication.shared.isNetworkActivityIndicatorVisible = false
  
  
                      if showSpinner {
                          HUD.flash(.labeledError(title: "Server issue", subtitle: "Invalid response"), delay: 2.0)
                      }
                      completionHandler(JSON.null, NSError(domain: "Invalid response", code: 420, userInfo: nil))
                  }
              }
          }
  
          task.resume()
      }
  }
  </code></pre>
  
  <p>So, to test this I have done this:</p>
  
  <pre><code>func testAPIWorking() {
      params = ["ios_token": "dq6YJkKwEx0:APA91bFeOTfJRFd5G78xMkv3AvjSLA7ey2dJxTZZAtMuuC50CqWILNzNjdgqVpNpDn7R4I0DLoydIVDYKubpGfgfu1bwz1H3VNU4D88ek8PJTAjxrd3CWkW78g0sNv6EZDLlTqUFeNxh", "api_token": "kfRSHL0bVP1fSmxNY3NfEGs8g0ktKCbTsPRRbfarh3a5ISIcZLu3qdK07MJ9H4rJ", "player_id": 8083]
  
      ServiceHelper.sharedInstance.sendRequest(path: "home", params: self.params, showSpinner: false) { (result, error) in
          if error != nil {
              XCTFail("Fail")
          }
          else {
  
          }       
      }
  }
  </code></pre>
  
  <p>I have added a breakpoint at task and it prints the task but then when I try to move to next line, instead of going into <code>Dispatch</code> it takes me out of that and stops at <code>task.resume()</code> and because of this I am not able to test the <code>errors</code> or expected <code>results</code>. Any help?</p>