当在Codable中进行日期比较时,如何解决单元测试中的错误 [英] How to resolve error in unit testing when we have Date comparison in Codable

查看:51
本文介绍了当在Codable中进行日期比较时,如何解决单元测试中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用 Codable 在json解码中使用自定义日期策略,如 https://stackoverflow.com/a/28016692/3477974 。这是简化的实现代码:

I tried to use custom date strategy in json decoding using Codable as describe in https://stackoverflow.com/a/28016692/3477974 . Here is the simplified implementation code:

public extension Formatter {
    static let iso8601: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
        return formatter
    }()
}

public extension Date {
    var iso8601: String {
        return Formatter.iso8601.string(from: self)
    }
}


public extension JSONDecoder.DateDecodingStrategy {
    static let iso8601withFractionalSeconds = custom {
        let container = try $0.singleValueContainer()
        let string = try container.decode(String.self)
        guard let date = Formatter.iso8601.date(from: string) else {
            throw DecodingError.dataCorruptedError(in: container,
                  debugDescription: "Invalid date: " + string)
        }
        return date
    }
}


public extension JSONEncoder.DateEncodingStrategy {
    static let iso8601withFractionalSeconds = custom {
        var container = $1.singleValueContainer()
        try container.encode(Formatter.iso8601.string(from: $0))
    }
}

但是,关于单元测试它失败,尽管错误消息显示描述的日期方法使用的值相等:

However, when it comes to unit testing it fails although the error message shows equal value used by description method of date:

    func test_jsonCodable_iso8601() {
        let dates = [Date()] // ["Feb 9, 2020 at 12:55:24 PM"]

        let encoder = JSONEncoder()
        encoder.dateEncodingStrategy = .iso8601withFractionalSeconds
        let data = try! encoder.encode(dates)

        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .iso8601withFractionalSeconds
        let decodedDates = try! decoder.decode([Date].self, from: data) // ["Feb 9, 2020 at 12:55:24 PM"]

        XCTAssertEqual(dates, decodedDates)
        // fails with error message: [2020-02-09 12:55:24 +0000]") is not equal to ("[2020-02-09 12:55:24 +0000]"
    }

您是否知道问题是什么以及如何解决?

Do you have any idea what is the issue and how we can resolve it?

顺便说一下,实际的可解码对象是以下类型,其中 publishedAt 的类型为date:

By the way, the actual decodable object is the following one where publishedAt is of type date:

public struct NewsItem: Equatable {
    public let id: UUID
    public let author: String
    public let title: String
    public let description: String
    public let urlToImage: URL?
    public let publishedAt: Date
    public let content: String

    public init(id: UUID,
                author: String,
                title: String,
                description: String,
                urlToImage: URL?,
                publishedAt: Date,
                content: String) {

        self.id = id
        self.author = author
        self.title = title
        self.description = description
        self.urlToImage = urlToImage
        self.publishedAt = publishedAt
        self.content = content
    }
}

extension NewsItem: Decodable {}


推荐答案

您要测试的是日期/ string转换,因此无需为此进行JSON编码和解码。以字符串形式的固定日期开始,将其转换为日期,然后返回并检查最终结果与固定日期

What you are testing is the date/string conversion so there is no need to involve JSON encoding and decoding into this. Start with a fixed date in string form, convert it to date and back and check the end result vs the fixed date

let input = "2020-02-02T19:10:23.123Z"

let formatter = DateFormatter.iso8601
let date = formatter.date(from: input)
let output = date?.iso8601

print(date != nil && input == output!)

请注意,这是在操场上编写的,而不是作为单元测试编写的

Note that this was written in a playground and not as a unit test

这篇关于当在Codable中进行日期比较时,如何解决单元测试中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆