Swift 使用SingleValueDecodingContainer对可解码的一致性进行单元测试
所以,我有一种类型,看起来像这样:Swift 使用SingleValueDecodingContainer对可解码的一致性进行单元测试,swift,unit-testing,codable,decodable,Swift,Unit Testing,Codable,Decodable,所以,我有一种类型,看起来像这样: struct Identifier { let string: String } extension Identifier: Decodable { public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() string = try container.decode(String.
struct Identifier {
let string: String
}
extension Identifier: Decodable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
string = try container.decode(String.self)
}
}
{
"identifier": "abc123",
// more properties ...
}
func testDecodableInit() {
let identifier = try! JSONDecoder().decode(Identifier.self, from: "1".data(using: .utf8)!)
XCTAssertEqual(identifier.string, "1")
}
这种类型的要点是,如果我有如下的JSON:
struct Identifier {
let string: String
}
extension Identifier: Decodable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
string = try container.decode(String.self)
}
}
{
"identifier": "abc123",
// more properties ...
}
func testDecodableInit() {
let identifier = try! JSONDecoder().decode(Identifier.self, from: "1".data(using: .utf8)!)
XCTAssertEqual(identifier.string, "1")
}
。。。它将自动序列化为正确的类型,无需花费太多精力。但是,在没有创建包装类型的情况下,我很难对这种与可解码的
的一致性进行单元测试
我想做的是这样的:
struct Identifier {
let string: String
}
extension Identifier: Decodable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
string = try container.decode(String.self)
}
}
{
"identifier": "abc123",
// more properties ...
}
func testDecodableInit() {
let identifier = try! JSONDecoder().decode(Identifier.self, from: "1".data(using: .utf8)!)
XCTAssertEqual(identifier.string, "1")
}
但显然这不起作用,因为“1”
不是有效的JSON
有没有可能在不创建包装类型并将数据更改为有效的JSON的情况下编写一个符合
Decodable
的单元测试呢?我放弃了在不创建包装类型的情况下完成这项工作,因为假设很难解码一个从一开始就不是有效的JSON的字符串('1'
在我的示例中)
所以,我想,答案是:只需创建一种包装类型。”\_(ツ)_/“如果有人想知道如何使用包装类型创建测试,它看起来是这样的
struct Identifier {
let string: String
}
extension Identifier: Decodable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
string = try container.decode(String.self)
}
}
class IdentifierTests: XCTestCase {
func testStringValueDecodedSuccessfully() throws {
let decoder = JSONDecoder()
let data = Data("{\"value\": \"identifier-string\"}".utf8)
let container = try decoder.decode(Wrapper1.self, from: data)
XCTAssertEqual(container.identifierValue.string, "identifier-string")
}
}
private struct Wrapper: Decodable {
let identifierValue: Identifier
enum CodingKeys: String, CodingKey {
case value
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
identifierValue = try container.decode(Identifier.self, forKey: .value)
}
}
我们的测试是这样的
struct Identifier {
let string: String
}
extension Identifier: Decodable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
string = try container.decode(String.self)
}
}
class IdentifierTests: XCTestCase {
func testStringValueDecodedSuccessfully() throws {
let decoder = JSONDecoder()
let data = Data("{\"value\": \"identifier-string\"}".utf8)
let container = try decoder.decode(Wrapper1.self, from: data)
XCTAssertEqual(container.identifierValue.string, "identifier-string")
}
}
private struct Wrapper: Decodable {
let identifierValue: Identifier
enum CodingKeys: String, CodingKey {
case value
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
identifierValue = try container.decode(Identifier.self, forKey: .value)
}
}
此测试的目标是什么?验证是否为无效/不正确的JSON引发错误?是的,JSON中表示的字符串可以转换为
标识符
。