我正在尝试使用URLSession.DataTaskPublisher为我的API编写一些单元测试。我已经在Stackoverflow上找到了一个已经存在的问题,但是我正在努力使用提出的解决方案来实现一个工作类。
这是现有的问题:How to mock URLSession.DataTaskPublisher
protocol APIDataTaskPublisher {
func dataTaskPublisher(for request: URLRequest) -> URLSession.DataTaskPublisher
}
class APISessionDataTaskPublisher: APIDataTaskPublisher {
func dataTaskPublisher(for request: URLRequest) -> URLSession.DataTaskPublisher {
return session.dataTaskPublisher(for: request)
}
var session: URLSession
init(session: URLSession = URLSession.shared) {
self.session = session
}
}
class URLSessionMock: APIDataTaskPublisher {
func dataTaskPublisher(for request: URLRequest) -> URLSession.DataTaskPublisher {
// How can I return a mocked URLSession.DataTaskPublisher here?
}
}
然后,我的API会像上面这样使用上面的代码:
class MyAPI {
/// Shared URL session
private let urlSession: APIDataTaskPublisher
init(urlSession: APIDataTaskPublisher = APISessionDataTaskPublisher(session: URLSession.shared)) {
self.urlSession = urlSession
}
}
我不知道如何实现URLSessionMock.dataTaskPublisher()。
最佳答案
模拟DataTaskPublisher
可能更简单而不是。您真的关心发布者是否是DataTaskPublisher
吗?可能不会。您可能关心的是获得与ojit_code相同的Output
和Failure
类型。因此,将您的API更改为仅指定以下内容:
protocol APIProvider {
typealias APIResponse = URLSession.DataTaskPublisher.Output
func apiResponse(for request: URLRequest) -> AnyPublisher<APIResponse, URLError>
}
使其符合
DataTaskPublisher
以供生产使用:extension URLSession: APIProvider {
func apiResponse(for request: URLRequest) -> AnyPublisher<APIResponse, URLError> {
return dataTaskPublisher(for: request).eraseToAnyPublisher()
}
}
然后,您的模拟就可以通过任何方便的方式来创建发布者。例如:
struct MockAPIProvider: APIProvider {
func apiResponse(for request: URLRequest) -> AnyPublisher<APIResponse, URLError> {
let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: "HTTP/1.1", headerFields: nil)!
let data = "Hello, world!".data(using: .utf8)!
return Just((data: data, response: response))
.setFailureType(to: URLError.self)
.eraseToAnyPublisher()
}
}
关于swift - 如何模拟DataTaskPublisher?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60089803/