概要
XCTestでJSONを生成する関数のテストコードを書いていました。
生成したJSONと期待されるJSONをXCTAssertEqual()
で比較する際は、JSONのkey値の順番を揃える必要があることを学びました。
詳細
つまずいたところ
最初に、生成したJSONと期待されるJSONのData型をXCTAssertEqual()
で比較した際、テストに通りませんでした。
調べてみたところ、JSONのkey順が等しくない場合XCTAssertEqual()
に通らないということがわかりました[1]。
解決方法
しかし、Dictionary型からJSONに変換する場合や、構造体からJSONに変換する場合、生成されたJSONのkey順は保証されません。
そのため、JSONに変換する際に.sortedKeys
を利用し、keyの順番を辞書式順序にソートすることで解決できることを学びました[1, 2]。
Dictionary型からJSONに変換する関数
具体例として、以下の関数でテストコードを書きました。
options: [.sortedKeys]
でkeyがソートされたJSONに変換されます。
JsonDataUtility.swift
struct JsonDataUtility {
func dictionaryToJson(data: [String: Any]) -> Data? {
do {
let jsonData = try JSONSerialization.data(withJSONObject: data, options: [.sortedKeys])
return jsonData
} catch {
print("エラー", error)
return nil
}
}
}
テストコード
生成結果と期待される結果はstring型で比較しています。
期待されるJSON文字列expectedJsonString
は、key値が辞書式順序(アルファベット順)になっています。
JsonDataUtilityTest.swift
import XCTest
@testable import TestApp
final class JsonDataUtilityTest: XCTestCase {
var util: JsonDataUtility!
override func setUp() {
super.setUp()
util = JsonDataUtility()
}
func testDictionaryToJson() {
let testData: [String: Any] = ["name": "John", "age": 30, "isStudent": true]
// 期待されるJSON文字列
let expectedJsonString = "{\"age\":30,\"isStudent\":true,\"name\":\"John\"}"
// 関数の実行
guard let jsonData = util.dictionaryToJson(data: testData) else {
XCTFail("dictionary型からjson型へのconvert失敗")
return
}
// JSONデータを文字列に変換
guard let jsonString = String(data: jsonData, encoding: .utf8) else {
XCTFail("json型からString型へのconvert失敗")
return
}
// Assert: 結果と想定される結果の評価
XCTAssertEqual(jsonString, expectedJsonString)
}
}