0

I wan't to write a unit tests for my APIClient. This is the method I would like to test:

typealias ResponsePublisher<T> = AnyPublisher<T, APIRequestError>

func dispatch<T: Decodable>(request: URLRequest) -> ResponsePublisher<T> {
        urlSession
            .dataTaskPublisher(for: request)
            .receive(on: DispatchQueue.global(qos: .background))
            .tryMap { data, response in
                if let response: HTTPURLResponse = response as? HTTPURLResponse,
                   !(200...299).contains(response.statusCode) {
                    throw APIClient.httpError(response.statusCode)
                }

                return data
            }
            .decode(type: T.self, decoder: JSONDecoder())
            .mapError { APIClient.handleNonHTTPError($0) }
            .eraseToAnyPublisher()
    }

What is the best solution/approach on how to properly mock a URLSession with mocked data, response and error by overriding method from the URLSession:

func dataTaskPublisher(for request: URLRequest) -> URLSession.DataTaskPublisher {}

which I use in dispatch method of the APIClient. In that case I would create an instance of a mocked URLSession and set it as urlSession property in my APIClient. It just needs to return mocked (data, response and error). Also the one possible limitation is with URLSession.DataTaskPublisher, since it is a struct it can not be overridden, so it can not be mocked directly. Thanks for your help and suggestions.

MattCodes
  • 489
  • 8
  • 21
  • [First google result](https://medium.com/@dhawaldawar/how-to-mock-urlsession-using-urlprotocol-8b74f389a67a) for "mock urlsession datatask". – Sweeper May 17 '23 at 01:27
  • This is not the same thing. I do not want to use closures and mock with them, if I wanted to implement with those I would use damn closures. I want to mock publisher from the Combine framework. This is not a duplicate questions. I could not find anything on how to mock APIClient with the dataTaskPublisher. – MattCodes May 17 '23 at 04:51
  • But you would do the same thing with `dataTaskPublisher(for:)` as they do with `dataTask(with:)` in the other answer. – Joakim Danielson May 17 '23 at 08:24
  • 1
    Or, instead try the approach used in [this answer](https://stackoverflow.com/a/61627636/9223839) – Joakim Danielson May 17 '23 at 08:28

0 Answers0