Browse Questions
Answer:
Use a protocol for URLSession or inject a custom URLProtocol subclass that intercepts requests and returns fake responses without hitting the network.
Code Example:
// Protocol approach — most common with async/await
protocol HTTPClient {
func data(from url: URL) async throws -> (Data, URLResponse)
}
extension URLSession: HTTPClient {}
// Mock for tests
class MockHTTPClient: HTTPClient {
var mockData: Data = Data()
var mockResponse: URLResponse = HTTPURLResponse(
url: URL(string: "https://example.com")!,
statusCode: 200, httpVersion: nil, headerFields: nil
)!
func data(from url: URL) async throws -> (Data, URLResponse) {
return (mockData, mockResponse)
}
}
// Inject into your service
class UserService {
private let client: HTTPClient
init(client: HTTPClient = URLSession.shared) { self.client = client }
}
// In tests
let mock = MockHTTPClient()
mock.mockData = try! JSONEncoder().encode(User.mock())
let service = UserService(client: mock)