VIPER 中的 dataTaskWithURL 崩溃单元测试 swift 4
dataTaskWithURL crash unit testing in VIPER with swift 4
我正在关注 this tutorial 并尝试对我的 Web 服务进行单元测试。教程在swift2,我写在swift4。
我一切正常,但应用程序崩溃了,无论是单元测试还是 运行 应用程序,我都不知道为什么。有人可以帮忙吗?
崩溃的代码行是:
extension URLSession : URLSessionProtocol{
func dataTaskWithURL(url: NSURL, completionHandler: (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTaskProtocol {
return dataTaskWithURL(url: url, completionHandler: completionHandler) //app crash
}
}
这是我的网络服务的完整代码:
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{
}
正如您所遵循的教程所解释的那样,URLSessionProtocol
的要点是复制您要测试的现有 URLSession
方法的函数签名。但是,您错误地更新了教程中的 Swift 2 代码,因此打破了这个假设。这导致 URLSession
没有自动符合 URLSessionProtocol
的问题,因此您尝试实际实现所需的协议方法,但协议并没有实际实现它,而是试图递归调用自身,导致无限递归.
您需要更改 URLSessionProtocol
的所需函数以完全匹配 URLSession
的 dataTask(with: <#T##URL#>, completionHandler: <#T##(Data?, URLResponse?, Error?) -> Void#>)
方法。
protocol URLSessionProtocol {
typealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void
func dataTask(with: URL, completionHandler: DataTaskResult) -> URLSessionDataTask
}
那么你只需要声明协议一致性,但实际上不需要实现所需的方法,因为它已经由 URLSession
:
实现了
extension URLSession: URLSessionProtocol {}
我正在关注 this tutorial 并尝试对我的 Web 服务进行单元测试。教程在swift2,我写在swift4。 我一切正常,但应用程序崩溃了,无论是单元测试还是 运行 应用程序,我都不知道为什么。有人可以帮忙吗?
崩溃的代码行是:
extension URLSession : URLSessionProtocol{
func dataTaskWithURL(url: NSURL, completionHandler: (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTaskProtocol {
return dataTaskWithURL(url: url, completionHandler: completionHandler) //app crash
}
}
这是我的网络服务的完整代码:
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{
}
正如您所遵循的教程所解释的那样,URLSessionProtocol
的要点是复制您要测试的现有 URLSession
方法的函数签名。但是,您错误地更新了教程中的 Swift 2 代码,因此打破了这个假设。这导致 URLSession
没有自动符合 URLSessionProtocol
的问题,因此您尝试实际实现所需的协议方法,但协议并没有实际实现它,而是试图递归调用自身,导致无限递归.
您需要更改 URLSessionProtocol
的所需函数以完全匹配 URLSession
的 dataTask(with: <#T##URL#>, completionHandler: <#T##(Data?, URLResponse?, Error?) -> Void#>)
方法。
protocol URLSessionProtocol {
typealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void
func dataTask(with: URL, completionHandler: DataTaskResult) -> URLSessionDataTask
}
那么你只需要声明协议一致性,但实际上不需要实现所需的方法,因为它已经由 URLSession
:
extension URLSession: URLSessionProtocol {}