我正在关注this tutorial并尝试对我的网络服务进行单元测试。该教程是 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{
}
最佳答案
正如您正在学习的教程所解释的那样, URLSessionProtocol
的要点就是复制现有URLSession
的函数签名您想要测试的方法。但是,您错误地更新了教程中的 Swift 2 代码,因此打破了这一假设。这导致了URLSession
的问题不自动符合URLSessionProtocol
,因此您尝试实际实现所需的协议(protocol)方法,但协议(protocol)并没有实际实现它,而是尝试递归调用自身,从而导致无限递归。
您需要更改URLSessionProtocol
所需的功能完全匹配dataTask(with: <#T##URL#>, completionHandler: <#T##(Data?, URLResponse?, Error?) -> Void#>)
方法URLSession
.
protocol URLSessionProtocol {
typealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void
func dataTask(with: URL, completionHandler: DataTaskResult) -> URLSessionDataTask
}
那么你只需要声明协议(protocol)一致性,但实际上不需要实现所需的方法,因为它已经由 URLSession
实现了:
extension URLSession: URLSessionProtocol {}
关于ios - 使用 swift 4 在 VIPER 中进行 dataTaskWithURL 崩溃单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52706087/