简体   繁体   中英

completion handler not getting called

I learned quite a comprehensive approach from this site . I customized it a bit to include an escaping closure, but its not getting called and I'm not receiving any response at the caller level.

I put break points within all guards to see if its exiting at some level, but so far no clue.

func getUsers(_ completion: @escaping (String?, NSException?) -> Void) {
    guard let url = URL(string: "http://127.0.0.1:8080/employees") else {
        completion(nil, NSException(name: NSExceptionName(rawValue: "Error"), reason: "Error validating URL.", userInfo: nil))
        return
    }
    
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    
    URLSession.shared.dataTask(with: request) { data, response, error in
        guard error == nil else {
            print("1")
            completion(nil, NSException(name: NSExceptionName(rawValue: "Error"), reason: error?.localizedDescription, userInfo: nil))
            return
        }
        
        guard let data = data else {
            print("2")
            completion(nil, NSException(name: NSExceptionName(rawValue: "Error"), reason: "Did not receive data.", userInfo: nil))
            return
        }
        
        guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
            print("3")
            completion(nil, NSException(name: NSExceptionName(rawValue: "Error"), reason: "HTTP request failed.", userInfo: nil))
            return
        }
        
        do {
            guard let jsonObject = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
                completion(nil, NSException(name: NSExceptionName(rawValue: "Error"), reason: "Cannot convert data to JSON object.", userInfo: nil))
                return
            }
            guard let prettyJsonData = try? JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted) else {
                completion(nil, NSException(name: NSExceptionName(rawValue: "Error"), reason: "Cannot convert JSON object to Pretty JSON data.", userInfo: nil))
                return
            }
            guard let prettyPrintedJson = String(data: prettyJsonData, encoding: .utf8) else {
                completion(nil, NSException(name: NSExceptionName(rawValue: "Error"), reason: "Could print JSON in String.", userInfo: nil))
                return
            }
            
            print(prettyPrintedJson)
            completion("done", nil)
            
        } catch {
            completion(nil, NSException(name: NSExceptionName(rawValue: "Error"), reason: "Trying to convert JSON data to string.", userInfo: nil))
            return
        }
        
    }.resume()
}

Usage

func testGetUsers() {
    userData.getUsers {
        print($0 ?? "result is nil")
        print($1?.name ?? "error is nil")
    }
}

Info.plist setting

在此处输入图像描述

In your test, you would use an expectation to wait for the closure to be called, eg

func testGetUsers() {
    let e = expectation(description: "testGetUsers")

    userData.getUsers {
        print($0 ?? "result is nil")
        print($1?.name ?? "error is nil")
        e.fulfill()
    }

    waitForExpectations(timeout: 10)
}

In most circles,.network requests are not considered unit tests. Often we would “mock” the.network responses and just test our app's ability to handle various types of responses. The goal of unit tests is not to test the integration with the back end, but rather to test how it would handle various theoretical responses.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM