-
-
Save seanlilmateus/58c7d255c8b6b209a966f5af5d456764 to your computer and use it in GitHub Desktop.
Mock URLSession using URLProtocol
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
class URLProtocolMock: URLProtocol { | |
/// Dictionary maps URLs to tuples of error, data, and response | |
static var mockURLs = [URL?: (error: Error?, data: Data?, response: HTTPURLResponse?)]() | |
override class func canInit(with request: URLRequest) -> Bool { | |
// Handle all types of requests | |
return true | |
} | |
override class func canonicalRequest(for request: URLRequest) -> URLRequest { | |
// Required to be implemented here. Just return what is passed | |
return request | |
} | |
override func startLoading() { | |
if let url = request.url { | |
if let (error, data, response) = URLProtocolMock.mockURLs[url] { | |
// We have a mock response specified so return it. | |
if let responseStrong = response { | |
self.client?.urlProtocol(self, didReceive: responseStrong, cacheStoragePolicy: .notAllowed) | |
} | |
// We have mocked data specified so return it. | |
if let dataStrong = data { | |
self.client?.urlProtocol(self, didLoad: dataStrong) | |
} | |
// We have a mocked error so return it. | |
if let errorStrong = error { | |
self.client?.urlProtocol(self, didFailWithError: errorStrong) | |
} | |
} | |
} | |
// Send the signal that we are done returning our mock response | |
self.client?.urlProtocolDidFinishLoading(self) | |
} | |
override func stopLoading() { | |
// Required to be implemented. Do nothing here. | |
} | |
} | |
// usage | |
let response = HTTPURLResponse(url: urlRequestedMock1, statusCode: 200, httpVersion: nil, headerFields: nil) | |
let error: Error? = nil | |
let data = """ | |
[ | |
{ | |
"someJsonKey": "someJsonData", | |
"anotherJsonKey": "anotherJsonData" | |
} | |
] | |
""".data(using: .utf8) | |
URLProtocolMock.mockURLs = [ | |
urlRequestedMock1: (error, data, response), | |
//... | |
] | |
let sessionConfiguration = URLSessionConfiguration.ephemeral | |
sessionConfiguration.protocolClasses = [URLProtocolMock.self] | |
let mockedSession = URLSession(configuration: sessionConfiguration) | |
let myAwesomeNetworkService = MyAwesomeNetworkService(urlSession: mockedSession) | |
myAwesomeNetworkService.fetchDataFromAwesomeUrl { response in | |
// your awesome assertions | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment