краш-тестирование dataTaskWithURL в VIPER с swift 4 - PullRequest
0 голосов
/ 08 октября 2018

Я слежу за этот учебник и пытаюсь провести модульное тестирование моих веб-сервисов.Учебное пособие написано на 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

    }
}

Вот полный код моего веб-сервиса:

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{

}

1 Ответ

0 голосов
/ 08 октября 2018

Как следует из учебного руководства, цель URLSessionProtocol - скопировать сигнатуру функции существующих URLSession методов, которые вы хотите протестировать.Однако вы неправильно обновили код Swift 2 из учебного пособия, что нарушает это предположение.Это привело к тому, что URLSession не соответствовал автоматически URLSessionProtocol, поэтому вы попытались фактически реализовать требуемый метод протокола, но вместо того, чтобы фактически реализовать его, протокол просто пытается рекурсивно вызвать себя, что приводит к бесконечной рекурсии.

Вам необходимо изменить требуемую функцию 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
}

Тогда вам просто нужно объявить соответствие протокола, но на самом деле это не так.необходимо реализовать требуемый метод, так как он уже реализован URLSession:

 extension URLSession: URLSessionProtocol {}
...