Created
March 3, 2024 08:25
-
-
Save MounikaMadishetti/36f860d7682cb443472733dcd5f65eec to your computer and use it in GitHub Desktop.
Create URLProtocol subclass for intercepting network requests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MARK: - Main Target | |
final class HTTPClient { | |
private let session: URLSession | |
init(session: URLSession = URLSession.shared) { | |
self.session = session | |
} | |
func get(from url: URL) { | |
session.dataTask(with: URLRequest(url: url)).resume() | |
} | |
} | |
// MARK: - Test Target | |
final class URLSessionHTTPClientTests: XCTestCase { | |
override func setUp() { | |
super.setUp() | |
URLProtocolStub.startInterceptingRequests() | |
} | |
override func tearDown() { | |
super.tearDown() | |
URLProtocolStub.stopInterceptingRequests() | |
} | |
func test_httpClient_loadsData() { | |
let data = Data(bytes: "anydata".utf8) | |
let url = URL(string: "https://www.any-url.com")! | |
let response = HTTPURLResponse(url: url, statusCode: 200, httpVersion: "", headerFields: nil)! | |
URLProtocolStub.stub(data: data, response: response, error: nil) | |
let sut = HTTPClient() | |
let expectation = expectation(description: "wait for completion") | |
sut.get(from: url) { result in | |
switch result { | |
case let .success(receivedData, receivedResponse): | |
XCTAssertEqual(receivedData, data) | |
XCTAssertEqual(receivedResponse.url, response.url) | |
XCTAssertEqual(receivedResponse.statusCode, response.statusCode) | |
default: | |
XCTFail("expected success receive \(result) instead") | |
} | |
expectation.fulfill() | |
} | |
wait(for: [expectation], timeout: 2.0) | |
} | |
} | |
class URLProtocolStub: URLProtocol { | |
static var stub: Stub? | |
struct Stub { | |
let data: Data? | |
let response: URLResponse? | |
let error: Error? | |
} | |
override class func canInit(with request: URLRequest) -> Bool { | |
return true | |
} | |
override class func canonicalRequest(for request: URLRequest) -> URLRequest { | |
request | |
} | |
override func startLoading() { | |
if let data = URLProtocolStub.stub?.data { | |
client?.urlProtocol(self, didLoad: data) | |
} | |
if let response = URLProtocolStub.stub?.response { | |
client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) | |
} | |
if let error = URLProtocolStub.stub?.error { | |
client?.urlProtocol(self, didFailWithError: error) | |
} | |
client?.urlProtocolDidFinishLoading(self) | |
} | |
override func stopLoading() { } | |
static func stub(data: Data?, response: URLResponse?, error: Error? = nil) { | |
stub = Stub(data: data, response: response, error: error) | |
} | |
static func startInterceptingRequests() { | |
URLProtocol.registerClass(URLProtocolStub.self) | |
} | |
static func stopInterceptingRequests() { | |
URLProtocol.unregisterClass(URLProtocolStub.self) | |
stub = nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment