Skip to content

Instantly share code, notes, and snippets.

@soujohnreis
Last active September 4, 2023 10:22
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save soujohnreis/7c86965efbbb2297d4db3f84027327c1 to your computer and use it in GitHub Desktop.
Save soujohnreis/7c86965efbbb2297d4db3f84027327c1 to your computer and use it in GitHub Desktop.
Mock URLSession using URLProtocol
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