🌊

【XCTest】URLProtocolを用いてURLSessionをモックする

2024/08/21に公開

後日執筆予定

final class CustomURLProtocol: URLProtocol {
    static var targets: [URL: (error: Error?, data: Data?, response: HTTPURLResponse?)] = .init()

    override class func canInit(with request: URLRequest) -> Bool { true }
    override class func canonicalRequest(for request: URLRequest) -> URLRequest { request }

    override func startLoading() {
        if let url = request.url {
            if let (error, data, response) = Self.targets[url] {
                if let response {
                    self.client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed)
                }

                if let data {
                    self.client?.urlProtocol(self, didLoad: data)
                }

                if let error {
                    self.client?.urlProtocol(self, didFailWithError: error)
                }
            }
        }

        self.client?.urlProtocolDidFinishLoading(self)
    }

    override func stopLoading() {}
}
let config = URLSessionConfiguration.ephemeral
config.protocolClasses = [CustomURLProtocol.self]

let urlSession = URLSession(configuration: config)

https://gist.github.com/soujohnreis/7c86965efbbb2297d4db3f84027327c1
https://developer.apple.com/documentation/xctest
https://sussan-po.com/2022/08/17/mocking-url-session/
https://engineering.nifty.co.jp/blog/27988
https://www.avanderlee.com/concurrency/unit-testing-async-await/

URLSession, URLProtocol, URLProtocolClient

Discussion