Skip to content

Instantly share code, notes, and snippets.

@punchdrunker
Last active February 7, 2023 01:13
Show Gist options
  • Save punchdrunker/07cfa5c492c3b784f66b43fcd9e491b8 to your computer and use it in GitHub Desktop.
Save punchdrunker/07cfa5c492c3b784f66b43fcd9e491b8 to your computer and use it in GitHub Desktop.
package tokyo.punchdrunker.playground
import com.google.gson.*
import org.junit.Assert
class GsonTester(val gson: Gson) {
/**
* json文字列をdeserialize後serializeし、余計なものが増えないか、必要な情報が欠落しないかの動作を確認する
*@paramjson元のjson
*@paramexpectedJsonDeserializeのみしか想定していないEntityクラス用に、ちょっといじったjsonでも比較できるように
*/
inline fun <reified T> testDeserializeAndSerialize(json: String, expectedJson: String? = null) {
val obj = gson.fromJson(json, T::class.java)
val serialized = gson.toJson(obj)
// 入力されたJSON文字列と、それをdeserialize -> serializeした文字列とを比較する
val expected = (expectedJson ?: json).toNormalizedJson()
val actual = serialized.toNormalizedJson()
Assert.assertEquals(expected, actual)
}
/**
* JSON文字列の比較時、キーの並び順の差異や改行、インデントは問題ではないので、それらの差異をNormalizeした文字列を返す。
*具体的にはキーをアルファベット順にソートした上でprettyした文字列を返す。
*/
fun String.toNormalizedJson(): String {
val element = JsonParser.parseString(this).normalize()
return GsonBuilder().setPrettyPrinting().create().toJson(element)
}
private fun JsonElement.normalize(): JsonElement {
return when (this) {
// JsonObjectについてはキーでソートする
is JsonObject -> JsonObject().also { obj ->
this.keySet().sorted().forEach { key ->
obj.add(key, this[key].normalize())
}
}
// JsonArrayについては各要素についてキーでソートする
is JsonArray -> JsonArray().also { array ->
this.forEach {
array.add(it.normalize())
}
}
else -> this
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment