我的网络模拟功能应包括什么?

时间:2019-01-16 16:50:14

标签: ios swift unit-testing

我想测试我的网络请求代码。测试不是我的强项,我这样做主要是为了更好地创建可测试的代码。我通常使用Alamofire,但想绕过它进行单元测试。我创建了这样的协议:

protocol NetworkSession {
    func request(
        _ endpoint: Endpoint,
        method: HTTPMethod,
        completion: @escaping (Result<<DataResponse<Any>>, RequestError>) -> ()
    )
}

我在课堂NetworkSessionManager中遵守此协议:

final class NetworkSessionManager : NetworkSession {
    func request(
        _ endpoint: Endpoint,
        method: HTTPMethod,
        completion: @escaping (Result<<DataResponse<Any>>, RequestError>) -> ()) {
        guard let url = endpoint.url else {
            return completion(.failure(.couldNotEncode))
        }
        Alamofire.request(url, method: method, headers: headers)
            .validate()
            .responseJSON { response in

                completion(.success(response))
            }
        }
    }
}

然后在我的BackendClient类中,我像这样注入并调用NetworkSessionManager

private let session: NetworkSession

init(session: NetworkSession = NetworkSessionManager()) {
    self.session = session
}


func someFunction(...) {
    session.request(...)
}

现在我知道我需要创建一个符合NetworkSession的模拟类,但是我不确定该怎么做?如何测试所有可能性和返回的数据?我的服务器上有不同的端点,它们返回不同类型的数据。如果有人可以指出我应该采取的下一步措施,我将不胜感激。

final class NetworkSessionManagerMock : NetworkSession {
    func request(
        _ endpoint: Endpoint,
        method: HTTPMethod,
        completion: @escaping (Result<<DataResponse<Any>>, RequestError>) -> ()) {
        ???
    }
}

1 个答案:

答案 0 :(得分:0)

我将展示两个示例,希望它们可以为您提供模拟NetworkSession的起点。

但是,首先,您可以向模拟类添加其他属性,这些属性支持注入值以测试各种情况。我将演示错误情况并立即返回。

enum MyError: Swift.Error {
    case failed
}

final class NetworkSessionManagerMock : NetworkSession {
    var myError: MyError?
    var dataResponse: Any? // This should hopefully be typed to something

    func request(
        _ endpoint: Endpoint,
        method: HTTPMethod,
        completion: @escaping (Result<<DataResponse<Any>>, RequestError>) -> ()) { [weak self] in 
        if let myError = self?.myError {
            // Send error with completion handler
        } else if let dataResponse = self?.dataResponse {
            // Send data response
        }
    }
}

这里的想法是您在测试中实例化模拟,然后根据需要设置变量以测试各个部分。然后您的模拟游戏将正常进行。

虽然我没有测试此代码的语法正确性,所以请告诉我其中是否有错误。