-
-
Save jellybeansoup/f750256e516348e735ce5f5d610f58da to your computer and use it in GitHub Desktop.
Stubbing URLSession
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
| import Foundation | |
| import Testing | |
| @Suite struct ExampleTests { | |
| @Test func example() async { | |
| struct Response: Stub { | |
| func stub(for request: URLRequest) -> (Data, URLResponse) { | |
| let data = Data(#"{"foo": "bar"}"#.utf8) | |
| let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)! | |
| return (data, response) | |
| } | |
| } | |
| let urlSession = URLSession.stubbed(with: Response.self) | |
| let (data, response) = urlSession.data(for: URL(string: "https://example.com") ) | |
| #expect(data == Data(#"{"foo": "bar"}"#.utf8)) | |
| #expect((response as? HTTPURLSession).statusCode == 200) | |
| } | |
| } |
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
| import Foundation | |
| public protocol Stub { | |
| static func stub(for request: URLRequest) throws -> (Data, URLResponse) | |
| } | |
| public extension URLSession { | |
| private class StubProtocol<S: Stub>: URLProtocol { | |
| override class func canInit(with request: URLRequest) -> Bool { | |
| true | |
| } | |
| override class func canonicalRequest(for request: URLRequest) -> URLRequest { | |
| request | |
| } | |
| override func startLoading() { | |
| guard let client else { return } | |
| do { | |
| let (data, response) = try S.stub(for: request) | |
| client.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) | |
| client.urlProtocol(self, didLoad: data) | |
| client.urlProtocolDidFinishLoading(self) | |
| } catch { | |
| client.urlProtocol(self, didFailWithError: error) | |
| } | |
| } | |
| override func stopLoading() {} | |
| } | |
| static func stubbed<S: Stub>(with stub: S.Type) -> URLSession { | |
| let config = URLSessionConfiguration.ephemeral | |
| config.protocolClasses = [StubProtocol<S>.self] | |
| return URLSession(configuration: config) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment