[英]How to stub URLSession in Swift?
我一直在关注本教程来删除URLSession
。 该示例是通过创建协议并扩展现有URLSession
。
protocol URLSessionProtocol {
typealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void
func dataTask(with request: NSURLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol
}
extension URLSession: URLSessionProtocol {
func dataTask(with request: NSURLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol {
return dataTask(with: request, completionHandler: completionHandler) as URLSessionDataTaskProtocol
}
}
单元测试按预期工作。 但是当我尝试运行真实的东西时, URLSession -> datatask() 进入无限循环并崩溃。 似乎 datatask() 正在调用自己。
请问我在看什么?
更新:
protocol URLSessionDataTaskProtocol {
var originalRequest: URLRequest? { get }
func resume()
}
extension URLSessionDataTask: URLSessionDataTaskProtocol {}
我终于找到了解决方案。 这很有趣,因为我们只见树木不见森林。 有两个问题:
1) Swift 4 似乎已经将dataTask(with: NSURLRequest)
的签名更改为dataTask(with: URLRequest)
因此,我的开头问题中的行只会与协议的 func 签名匹配,并且它永远不会命中dataTask
URLSession
,因此是无限循环。 为了解决这个问题,我不得不将NSURLRequest
更改为URLRequest
并相应地重构代码。
2) 签名仍然模糊,因此最好先将结果存储为URLSessionDataTask
,然后转换为URLSessionDataTask
,然后返回变量。
Swift 4 的新重构代码:
typealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void
protocol URLSessionProtocol {
func dataTask(with request: URLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol
}
extension URLSession: URLSessionProtocol {
func dataTask(with request: URLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol {
let task:URLSessionDataTask = dataTask(with: request, completionHandler: {
(data:Data?, response:URLResponse?, error:Error?) in completionHandler(data,response,error) }) as URLSessionDataTask
return task
}
}
我还发现我必须将URLSession.shared
作为单例而不是URLSession()
注入,否则它可能会崩溃。
来到这里是为了了解如何模拟URLSession
任务,例如URLSessionDataTask
?
大约5斯威夫特,这是很容易嘲笑URLProtocol
是URLSession
使用发送请求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.