I'm currently trying out a method of stubbing my network requests without needing to mock URLSession
by using URLProtocol
.
So far it works pretty well and functions by calling self.client?.urlProtocol(_ URLProtocol, didLoad: Data)
. However I'm unable to pass nil
so I can test how my networking class handles being sent a successful response with no data (i.e. a HTTP 204 code). By default URLProtocol returns an empty Data
object rather than nil so this does appear to be something I have to set manually.
Is there a way of returning a successful response with nil Data using a URLProtocol subclass? After searching the documentation I can't find anything that jumps out although it seems likely this is possible.
URLProtocolStub
// Custom URLProtocol to be used in place of Apple's HTTP protocols when
// testing network code
class URLProtocolStub: URLProtocol {
static var testURLs = [URL?: Data]()
override class func canInit(with request: URLRequest) -> Bool {
return true
}
override class func canonicalRequest(for request: URLRequest) -> URLRequest {
return request
}
override func startLoading() {
if let url = request.url,
let data = Self.testURLs[url] {
self.client?.urlProtocol(self, didLoad: data)
}
client?.urlProtocolDidFinishLoading(self)
}
override func stopLoading() {}
}
Code to be tested
func requestCards(completionHandler:@escaping (Result<[Card],NetworkCallError>) -> Void ) {
session.dataTask(with: URL(string: "https://deckofcardsapi.com/api/deck/new/draw/?count=52")!) { data, response, error in
guard let data = data else {
completionHandler(.failure(.noData))
return
}