ios - 如何在 Swift 4 中测试 API?
问题描述
我是单元测试的新手。我已经测试了很多功能并且我理解了这个概念,现在我想检查 API。可能吗?大概吧。这是 API:
func sendRequest(path: String, params: Dictionary<String, Any>, showSpinner: Bool, completionHandler: @escaping (JSON, Error?) -> 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()
}
}
所以,为了测试这个,我做了这个:
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 {
}
}
}
我在任务处添加了一个断点,它会打印任务,但是当我尝试移至下一行时,我没有进入Dispatch
它,而是将我带出并停在此处,task.resume()
因此我无法测试errors
or 预期的results
. 有什么帮助吗?
解决方案
这里有一个完成处理程序,api 调用不同步。所以你应该在你的测试中等待结果。在 Xcode 中,您可以使用XCTestExpectation
.
例如:
func testAPIWorking()
{
let expectation = XCTestExpectation.init(description: "Your expectation")
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")
}
// The request is finished, so our expectation
expectation.fulfill()
}
// We ask the unit test to wait our expectation to finish.
self.waitForExpectations(timeout: 20)
}
推荐阅读
- javascript - 如何从 React Native 中的两个数组中提取不相同的元素?
- angular - 角度如果传递2个数据的问题
- git - 如何在不每次都下载完整设置的情况下升级到 GIT 最新版本?
- powershell - 如何用单个回车替换多个回车/换行符?
- hibernate - 二级休眠缓存 - 使对象在会话工厂级别可用?
- javascript - Promise 不能解决这个问题
- delphi - 可以拦截对现有已发布属性的读取
- mysql - prolog 在 web 中显示多个 mysql 记录
- go - 如何在没有指数的情况下从 json 的 map[string]interface{} 格式化 int 数?
- python - Window.screenshot 在 iOS 上返回黑屏