XCTest中URLSession发起GET请求无法获取API响应问题
问题解决:XCTest中异步API请求无法获取响应
核心原因
XCTest测试方法默认是同步执行的,当你调用异步的requestAPIInfo方法后,测试方法会直接执行完毕并结束,此时网络请求的异步闭包还没来得及执行,所以看不到任何打印或响应结果。
解决方案
1. 给测试添加异步等待机制
在UI测试代码中,通过XCTestExpectation让测试等待异步任务完成:
func testAPIRequest() { let temp = APIHelpers() // 创建期望对象,标记需要等待的任务 let apiExpectation = XCTestExpectation(description: "等待API请求返回结果") temp.requestAPIInfo { apiResult in print(apiResult) // 任务完成后标记期望达成 apiExpectation.fulfill() } // 设置超时时间,等待期望完成 wait(for: [apiExpectation], timeout: 10.0) }
2. 修复APIHelpers中的潜在问题
你的API工具类里有几个隐藏风险,优化后能避免静默失败:
- 不再强制解包URL,处理初始化失败的场景
- 增加响应数据的空值判断,避免崩溃
- 解码失败时调用completion,让测试能捕获错误
- 实际使用创建好的
URLRequest(之前代码中创建了但没用到)
优化后的APIHelpers代码:
import Foundation struct Example: Decodable { let userId: Int let id: Int let title: String let completed: Bool } struct APIHelpers { let resourceURL: URL? let urlString = "https://jsonplaceholder.typicode.com/todos/1" init() { resourceURL = URL(string: urlString) } func requestAPIInfo(completion: @escaping(Result<Example, Error>) -> Void) { guard let url = resourceURL else { completion(.failure(NSError(domain: "APIHelpers", code: -1, userInfo: [NSLocalizedDescriptionKey: "URL初始化失败"]))) return } var request = URLRequest(url: url) request.httpMethod = "GET" let dataTask = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print(error.localizedDescription) completion(.failure(error)) return } guard let responseData = data else { let emptyDataError = NSError(domain: "APIHelpers", code: -2, userInfo: [NSLocalizedDescriptionKey: "未获取到响应数据"]) print(emptyDataError.localizedDescription) completion(.failure(emptyDataError)) return } let decoder = JSONDecoder() do { let jsonData = try decoder.decode(Example.self, from: responseData) completion(.success(jsonData)) } catch { print("JSON解码错误: \(error)") completion(.failure(error)) } } dataTask.resume() } }
验证方式
- 把UI测试代码替换为带
XCTestExpectation的版本 - 替换优化后的APIHelpers代码
- 重新运行测试,此时测试会等待API请求完成,控制台就能打印出响应结果
内容的提问来源于stack exchange,提问作者GreyndBlue
相关产品推荐
相关产品推荐

