- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个使用泛型的网络层,我正在使用协议(protocol)以便稍后测试它。我已遵循本教程 https://medium.com/thecocoapps/network-layer-in-swift-4-0-972bf2ea5033
这是我的测试模拟:
import Foundation
@testable import TraktTest
class MockUrlSessionProvider: ProviderProtocol {
enum Mode {
case success
case empty
case fail
}
private var mode: Mode
init(mode: Mode) {
self.mode = mode
}
func request<T>(type: T.Type, service: ServiceProtocol, completion: @escaping (NetworkResponse<T>) -> Void) where T: Decodable {
switch mode {
case .success: completion(NetworkResponse.success(T))
case .empty: completion(.failure(.noData))
case .fail: completion(.failure(.unknown("Error")))
}
}
}
我收到错误:Cannot convert value of type 'NetworkResponse<T.Type>' to expected argument type 'NetworkResponse<_>'
在这一行:完成(NetworkResponse.success(T))
如果我将其发送到我的完成成功,它会编译: try? JSONDecoder().decode(T.self, from: data!)
(我使用编码和我的模型创建的虚拟数据),但是在进入我的模型时崩溃,因为尽管我使用 JSONEncoder() 和正确的模型进行了编码,但它还是 nil。
我认为它有效,因为我在我的应用程序中实现 ProviderProtocol 的类中使用的逻辑相同:
final class URLSessionProvider: ProviderProtocol {
private var session: URLSessionProtocol
init(session: URLSessionProtocol = URLSession.shared) {
self.session = session
}
func request<T>(type: T.Type, service: ServiceProtocol, completion: @escaping (NetworkResponse<T>) -> Void) where T: Decodable {
let request = URLRequest(service: service)
session.dataTask(request: request) { [weak self] data, response, error in
let httpResponse = response as? HTTPURLResponse
self?.handleDataResponse(data: data, response: httpResponse, error: error, completion: completion)
}.resume()
}
private func handleDataResponse<T: Decodable>(data: Data?, response: HTTPURLResponse?, error: Error?, completion: (NetworkResponse<T>) -> Void) {
guard error == nil else { return completion(.failure(.unknown(error?.localizedDescription ?? "Error"))) }
guard let response = response else { return completion(.failure(.unknown("no_response".localized()))) }
switch response.statusCode {
case 200...299:
guard let data = data, let model = try? JSONDecoder().decode(T.self, from: data) else { return completion(.failure(.noData)) }
completion(.success(model))
default: completion(.failure(.unknown("no_response".localized())))
}
}
}
URLSessionProtocol 只是一个协议(protocol),它有一个与 URLSession.shared 相同的方法 dataTask(接收 URLRequest 并在完成时返回数据、响应和错误)。
我的网络响应是几个枚举:
enum NetworkResponse<T> {
case success(T)
case failure(NetworkError)
}
enum NetworkError {
case unknown(String)
case noData
}
我的提供者协议(protocol)只有一个函数可以使用泛型发出请求:
protocol ProviderProtocol {
func request<T>(type: T.Type, service: ServiceProtocol, completion: @escaping(NetworkResponse<T>) -> Void) where T: Decodable
}
我不认为我需要在我的测试中使用 ServiceProtocol,因为要使用端点、 header 、正文、id 等设置请求。但这是我创建的协议(protocol):
typealias Headers = [String: String]
typealias Parameters = [String: Any]
protocol ServiceProtocol {
func baseURL() -> URL
var path: String? { get }
var id: String? { get }
var method: HTTPMethod { get }
var task: Task { get }
var headers: Headers? { get }
var parametersEncoding: ParametersEncoding { get }
}
enum HTTPMethod: String {
case get = "GET"
case post = "POST"
}
enum Task {
case requestPlain
case requestParameters(Parameters)
}
enum ParametersEncoding {
case url
case json
}
在我的应用程序中,我有一个实现 ProviderProtocol 的类,并在某些 viewModel 使用适当的模型调用请求时使用 URLSession.shared 来创建 dataTask。
我习惯使用协议(protocol)和特定模型进行测试,但使用泛型会向我显示该错误。我怎样才能拥有一个使用泛型的模拟提供者,这样我就可以测试任何使用不同类型的模型( stub )调用网络的 viewModel。
最佳答案
错误的发生是因为 NetworkResponse
需要一个 T
的实例,而 mock 试图提供实际的 T
。
因此,您需要以某种方式提供一个实例,但是模拟无法生成该实例,因为它没有关于如何构建实例的足够信息。
我建议在创建模拟时从外部注入(inject)成功值。您可以通过使模拟类通用,或通过使 Mode
枚举通用来实现这一点。下面是后者的示例实现:
class MockUrlSessionProvider: ProviderProtocol {
// making the enum generic, to support injecting the success value
enum Mode<T> {
case success(T)
case empty
case fail
}
// need to have this as `Any` to cover all possible T generic arguments
private var mode: Any
// however the initializer can be very specific
init<T>(mode: Mode<T>) {
self.mode = mode
}
func request<T>(type: T.Type, service: ServiceProtocol, completion: @escaping (NetworkResponse<T>) -> Void) where T: Decodable {
// if the mock was not properly configured, do nothing
guard let mode = mode as? Mode<T> else { return }
// alternatively you force cast and have the unit test crash, this should help catching early configuration issues
// let mode = mode as! Mode<T>
switch mode {
case let .success(value): completion(NetworkResponse.success(value))
case .empty: completion(.failure(.noData))
case .fail: completion(.failure(.unknown("Error")))
}
}
}
关于swift - 无法将类型 'MyEnum<T.Type>' 的值转换为预期的参数类型 'MyEnum<_>',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54424326/
我有以下枚举: public enum myEnum { ONE("ONE"), TWO("TWO"); private String name; private myEnum
MyEnum.Item.ToString(); nameof(MyEnum.Item); 哪种风格是首选?两者之间有什么实际区别吗? 最佳答案 第一个是运行时调用,它将在运行时意识到它需要返回字符串
我有一个使用泛型的网络层,我正在使用协议(protocol)以便稍后测试它。我已遵循本教程 https://medium.com/thecocoapps/network-layer-in-swift-
我为我的枚举创建了 Enum ToFrendlyString 函数,但我不能在 Linq 中使用。 public enum MyEnum { Queued = 0,
我需要序列化和反序列化Set使用mybatis。序列化时效果很好,但得到 Set反序列化时。这是我的代码: mybatis-config.xml: 我的枚举:
我正在尝试将一些 VB.net 代码转换为 C#。我使用 SharpDevelop 来完成繁重的工作;但它生成的代码在某些枚举操作上出现问题,我不确定如何手动修复它。 原始 VB.net 代码: En
我正在尝试从我正在处理的类(class)中删除警告。 警告如下: Warning C4482: nonstandard extension used: enum 'MyEnum' used in qu
我在我的框架中的一个类中有一个带有原始值的枚举,我想将其与另一个类一起使用。我收到以下错误。 'types' is inaccessible due to 'internal' protection
我有一些模型 Dictionary .当我尝试使用 C# 驱动程序插入 mongoDB 时,出现异常并显示以下消息: When using DictionaryRepresentation.Docum
我有一个枚举定义为: enum AlertInterfaceControllerKey { case Title case Content } 我想在呈现 WKInterfaceCon
我正在使用Spring的BeanPropertyRowMapper将来自数据库的行映射到我的Bean类Employee,Enum有2种类型,Active,Inactive。当 beanproperty
好吧,我想做这个工作 public static void main(String[] args) { int cityId = 1234; switch (cityId) {
更新,添加评论中的问题: what's the best way to get the Map into Map where Foo is an Enum. it just seems awfully
我将 WinGrid 中的一些数据转换为表达式,以便向用户过滤一些输出。 我有一个初始集合(MyObjectType),我应用了一些动态过滤器,并获得了一个过滤集合。 但是,我遇到了枚举 - MyOb
我想用一些Map如@RequestParam在我的 Spring Controller 中。现在我做了以下事情: public enum MyEnum { TESTA("TESTA"),
对于撇油器。问题位于粗体文本之后的底部附近。 我正在对 ComboBox 进行数据绑定(bind)使用 ObjectDataProvider 转换为枚举类型. ObjectDataProvider很简
我们是否应该使用 Enum 作为 HashMap 中的键存储数据来代替字符串键 Ex。 HashMap myMap 与字符串相比,在 HashMap 中使用枚举作为键是否存在任何性能问题。哪一种是使用
我一直在尝试重载运算符 #include /* (global scope) */ enum class enum_type_1 { e1_enumerand }; inline std::ostr
我是一名优秀的程序员,十分优秀!