Thanks in advance for any advice!
I'm setting up some unit tests in swift for iOS development. The method requires a call to the keychain to create an authToken to successfully run the function. I'm not sure how to approach creating a unit test for this kind of environment. Do I mock up a local file that I can use to bypass the authentication? Do I try to skip the authentication step entirely?
The function I'm testing is a private function as well and I'm having a hard time conceptualizing how I can test it through the public methods. Here is the code I'm working with:
override func viewDidLoad() {
super.viewDidLoad()
self.setMyDoctorsNavBarTitle()
self.setBackgroundWaterMark()
self.getDoctors()
//self.refreshControl?.addTarget(self, action: #selector(MyDoctorsViewController.refresh(_:)), forControlEvents: UIControlEvents.ValueChanged)
}
private func getDoctors() {
let authToken: [String: AnyObject] = [ "Authorization": keychain["Authorization"]!, // creates an authToken with the current values stored in
"UUID": keychain["UUID"]!, "LifeTime": keychain["LifeTime"]! ] // the keychain
RestApiManager.sharedInstance.postMyDocs(authToken) { (json, statusCode) in // passes the created authToken to postMyDocs in RestAPI to see if
if statusCode == 200 { // the token matches what's on the server
if let results = json["Doctors"].array { // If the credentials pass, we grab the json file and create an array of Doctors
for entry in results {
self.buildDoctorObject(entry) // Doctors information is parsed into individual objects
}
}
} else if statusCode == 401 {
/* If statucCode is 401, the user's AuthToken has expired. The historical AuthToken data will be removed from the iOS KeyChain and the user will be redirected to the login screen to reauthorize with the API
*/
self.keychain["Authorization"] = nil
self.keychain["UUID"] = nil
self.keychain["LifeTime"] = nil
let loginController = self.storyboard?.instantiateViewControllerWithIdentifier("LoginViewController") as! LoginViewController
NSOperationQueue.mainQueue().addOperationWithBlock {
self.presentViewController(loginController, animated: true, completion: nil)
}
} else if statusCode == 503 {
print("Service Unavailable Please Try Again Later")
}
}
}
private func buildDoctorObject(json: JSON){
let fName = json["FirstName"].stringValue
let lName = json["LastName"].stringValue
let city = json["City"].stringValue
let phNum = json["PhoneNumber"].stringValue
let faxNum = json["FaxNumber"].stringValue
let state = json["State"].stringValue
let addr = json["Address"].stringValue
let img = json["Image"].stringValue
let zip = json["Zip"].stringValue
let tax = json["Taxonomy"].stringValue
let docObj = DoctorObject(fName: fName, lName: lName, addr: addr, city: city, state: state, zip: zip, phNum: phNum, faxNum: faxNum, img: img, tax: tax)
self.docs.append(docObj)
self.tableView.reloadData()
}
I want to be able to Unit Test the getDoctors() and buildDoctorObject() functions, but I can only do that indirectly through viewDidLoad() since they're private.
I want to be able to test that the statusCode is being brought down correctly from the server and the appropriate steps take place if it comes back as 200 or 401.
I'm not necessarily looking for complete code, but simply a way to approach the problem. If you know of resources that might be helpful I would be grateful. I'm very new to this and I tried looking into resources online but couldn't find anything. A lot of what I found was you don't want to test private functions directly, and isn't advised to change the functions to public for the sake of testing.
Thanks again for looking into it!
Sean W.