我想针对我的网络代码编写单元测试。
我想断言我的主机设置正确。
我的网络代码使用泛型,因此我可以基于调用的终点传入预期的响应模型。
我的XCTTestCase
如下:
@testable import Home
import XCTest
class APIClientTests: XCTestCase {
var sut: APIClient!
var mockURLSession: MockURLSession!
override func setUp() {
sut = APIClient()
mockURLSession = MockURLSession(data: nil, urlResponse: nil, error: nil)
sut.session = mockURLSession
}
func test_Execute_UsesCorrectHost() {
guard let request = createURLObject("https://foo.bar.com") else { XCTFail("Could not create URL object"); return }
let completion = { (Result<String>) in }
sut.call(with: request, completion: completion)
XCTAssertEqual(mockURLSession?.urlComponents?.host, "foo.bar")
}
}
extension APIClientTests {
class MockURLSession: SessionProtocol {
var url: URL?
private let dataTask: MockTask
var urlComponents: URLComponents? {
guard let url = url else { return nil }
return URLComponents(url: url, resolvingAgainstBaseURL: true)
}
init(data: Data?, urlResponse: URLResponse?, error: Error?) {
dataTask = MockTask(data: data, urlResponse: urlResponse, error: error)
}
func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
self.url = url
dataTask.completionHandler = completionHandler
return dataTask
}
}
class MockTask: URLSessionDataTask {
private let data: Data?
private let urlResponse: URLResponse?
private let responseError: Error?
typealias CompletionHandler = (Data?, URLResponse?, Error?) -> Void
var completionHandler: CompletionHandler?
init(data: Data?, urlResponse: URLResponse?, error: Error?) {
self.data = data
self.urlResponse = urlResponse
responseError = error
}
override func resume() {
DispatchQueue.main.async { [weak self] in
self?.completionHandler?(self?.data, self?.urlResponse, self?.responseError)
}
}
}
func createURLObject(_ url: String) -> URLRequest? {
guard let url = URL(string: url) else { return nil }
return URLRequest(url: url)
}
}
我要测试的代码如下
import Foundation
enum Result<T> {
case success(T)
case failure(String)
}
protocol SessionProtocol {
func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?)-> Void) -> URLSessionDataTask
}
protocol APIClientProtocol {
var session: SessionProtocol { mutating get }
func call<T: Codable>(with request: URLRequest, completion: @escaping (Result<T>) -> Void) -> Void
}
struct APIClient: APIClientProtocol {
lazy var session: SessionProtocol = URLSession.shared
func call<T: Codable>(with request: URLRequest, completion: @escaping (Result<T>) -> Void) -> Void { }
}
extension URLSession: SessionProtocol { }
代替这一行:
let completion = { (Result<String>) in }
我遇到以下错误:
无法推断复杂的闭包返回类型;添加显式类型 消除期望参数名称的歧义,后跟':'