我正在关注this tutorial,并试图对我的Web服务进行单元测试。本教程位于swift 2中,我已将其编写为swift 4。 我一切正常,但是应用程序崩溃了,无论我是进行单元测试还是运行应用程序,我都无法理解为什么。有人可以帮忙吗?
崩溃的代码行是:
extension URLSession : URLSessionProtocol{
func dataTaskWithURL(url: NSURL, completionHandler: (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTaskProtocol {
return dataTaskWithURL(url: url, completionHandler: completionHandler) //app crash
}
}
这是我的webService的完整代码:
import Foundation
protocol URLSessionProtocol {
typealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void
func dataTaskWithURL(url: NSURL, completionHandler: DataTaskResult)
-> URLSessionDataTaskProtocol
}
protocol URLSessionDataTaskProtocol {
func resume()
}
class UserListRemoteDataManager:UserListRemoteDataManagerInputProtocol {
var remoteRequestHandler: UserListRemoteDataManagerOutputProtocol?
private let session : URLSessionProtocol
init(session : URLSessionProtocol) {
self.session = session
}
func retrieveUsers() {
if let url = NSURL(string: Endpoints.Users.fetch.url){
session.dataTaskWithURL(url: url, completionHandler: { (data, response, error) in
if error != nil {
print(error as Any)
}
if error == nil && data != nil {
do{
let users = try JSONDecoder().decode(UserModel.self, from: data!)
self.remoteRequestHandler?.onUsersRetrieved(users.users)
}catch let error as NSError {
print(error)
self.remoteRequestHandler?.onError()
}
}
}).resume()
}
}
}
extension URLSession : URLSessionProtocol{
func dataTaskWithURL(url: NSURL, completionHandler: (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTaskProtocol {
return dataTaskWithURL(url: url, completionHandler: completionHandler) //app crash
}
}
extension URLSessionDataTask : URLSessionDataTaskProtocol{
}
答案 0 :(得分:0)
正如您要学习的教程所解释的,URLSessionProtocol
的重点是复制要测试的现有URLSession
方法的函数签名。但是,您从教程中错误地更新了Swift 2代码,从而打破了这一假设。这导致URLSession
不能自动符合URLSessionProtocol
的问题,因此您尝试实际实现所需的协议方法,但实际上没有实现,而是协议尝试递归调用自身,从而导致无限递归
您需要更改URLSessionProtocol
的必需功能以与dataTask(with: <#T##URL#>, completionHandler: <#T##(Data?, URLResponse?, Error?) -> Void#>)
的{{1}}方法完全匹配。
URLSession
然后,您只需要声明协议一致性,而实际上不需要实现所需的方法,因为protocol URLSessionProtocol {
typealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void
func dataTask(with: URL, completionHandler: DataTaskResult) -> URLSessionDataTask
}
已经实现了该方法:
URLSession