Last active
May 31, 2020 07:40
-
-
Save yutailang0119/c75ae0f15b0e5040c1c6c5b86c6bc77a to your computer and use it in GitHub Desktop.
Mock Swift APIClient with Combine
This file contains 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
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, macCatalyst 13.0, *) | |
// MARK: - Request | |
protocol Request { | |
associatedtype Response: Decodable | |
var urlRequest: URLRequest { get } | |
} | |
// MARK: - APISession | |
public protocol APISession { | |
func dataTaskPublisher<R: Request>(for request: R) -> AnyPublisher<(data: Data, response: URLResponse), URLError> | |
} | |
public protocol APISession { | |
func dataTaskPublisher<R: Request>(for request: R) -> AnyPublisher<(data: Data, response: URLResponse), URLError> | |
} | |
// MARK: - APIClient | |
protocol APIClient { | |
associatedtype Session: APISession | |
var session: Session { get } | |
func request<R: Request>(of request: R) -> AnyPublisher<R.Response, Error> | |
} | |
public extension APIClient { | |
func request<R: Request>(of request: R) -> AnyPublisher<R.Response, Error> { | |
session | |
.dataTaskPublisher(for: request) | |
.tryMap { data, response in | |
// something | |
} | |
.eraseToAnyPublisher() | |
} | |
} | |
// MARK: - Mock | |
class MockAPIClient: APIClient { | |
let session = MockAPISession() | |
} | |
class MockAPISession: APISession { | |
func dataTaskPublisher<R: Request>(for request: R) -> AnyPublisher<(data: Data, response: URLResponse), URLError> { | |
MockDataTaskPublisher(request: request) | |
.eraseToAnyPublisher() | |
} | |
} | |
struct MockDataTaskPublisher<R: Request>: Publisher { | |
typealias Output = (data: Data, response: URLResponse) | |
typealias Failure = URLError | |
let request: R | |
func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input { | |
// something | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment