Я получаю следующий JSON из сетевого запроса:
{
"uvIndex": 5
}
Я использую следующий тип для декодирования результата преобразования строки в данные:
internal final class DataDecoder<T: Decodable> {
internal final class func decode(_ data: Data) -> T? {
return try? JSONDecoder().decode(T.self, from: data)
}
}
Ниже представлена модель, в которую должны быть преобразованы данные:
internal struct CurrentWeatherReport: Codable {
// MARK: Properties
internal var uvIndex: Int?
// MARK: CodingKeys
private enum CodingKeys: String, CodingKey {
case uvIndex
}
// MARK: Initializers
internal init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let uvIndexInteger = try container.decodeIfPresent(Int.self, forKey: .uvIndex) {
uvIndex = uvIndexInteger
} else if let uvIndexString = try container.decodeIfPresent(String.self, forKey: .uvIndex) {
uvIndex = Int(uvIndexString)
}
}
}
Ниже приведены тесты, используемые для проверки декодирования:
internal final class CurrentWeatherReportTests: XCTestCase {
internal final func test_CurrentWeather_ReturnsExpected_UVIndex_FromIntegerValue() {
let string =
"""
{
"uvIndex": 5
}
"""
let data = DataUtility.data(from: string)
let currentWeatherReport = DataDecoder<CurrentWeatherReport>.decode(data)
XCTAssertEqual(currentWeatherReport?.uvIndex, 5)
}
internal final func test_CurrentWeather_ReturnsExpected_UVIndex_FromStringValue() {
let string =
"""
{
"uvIndex": "5"
}
"""
let data = DataUtility.data(from: string)
let currentWeatherReport = DataDecoder<CurrentWeatherReport>.decode(data)
XCTAssertEqual(currentWeatherReport?.uvIndex, 5)
}
}
Разница между тестами заключается в значении uvIndex
в JSON; один представляет собой строку, а другой - целое число. Я ожидаю целое число, но я хочу обрабатывать любые случаи, когда значение может вернуться в виде строки, а не числа, поскольку это обычная практика для нескольких API, с которыми я работаю. Однако мой второй тест продолжает давать сбой со следующим сообщением: XCTAssertEqual failed: ("nil") is not equal to ("Optional(5)") -
Я делаю что-то неправильно в отношении протокола Codable
, который вызывает этот сбой? Если нет, то почему мой второй тест с этим, казалось бы, простым приведением не проходит?