Skip to content

Instantly share code, notes, and snippets.

@punchdrunker
Created February 2, 2023 01:07
Show Gist options
  • Save punchdrunker/6e0ffb41fb2a5f531889fb5ae4705178 to your computer and use it in GitHub Desktop.
Save punchdrunker/6e0ffb41fb2a5f531889fb5ae4705178 to your computer and use it in GitHub Desktop.
package tokyo.punchdrunker.playground
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.*
import org.junit.Assert
class KSerializationTester(val kotlinxJson: Json) {
/**
* json文字列をdeserialize後serializeし、余計なものが増えないか、必要な情報が欠落しないかの動作を確認する
* @param json 元のjson
* @param expectedJson Deserializeのみしか想定していないEntityクラス用に、ちょっといじったjsonでも比較できるように
*/
inline fun <reified T> testDeserializeAndSerialize(
json: String,
expectedJson: String? = null,
noinline deserializedObjectTester: ((value: T) -> Unit)? = null,
) {
val obj = kotlinxJson.decodeFromString<T>(json)
deserializedObjectTester?.invoke(obj)
val serialized = kotlinxJson.encodeToString(obj)
// 入力されたJSON文字列と、それをdeserialize -> serializeした文字列とを比較する
val expected = (expectedJson ?: json).toNormalizedJson()
val actual = serialized.toNormalizedJson()
Assert.assertEquals(expected, actual)
}
private val jsonEncoder by lazy { Json { prettyPrint = true } }
/**
* JSON文字列の比較時、キーの並び順の差異や改行、インデントは問題ではないので、それらの差異をNormalizeした文字列を返す。
* 具体的にはキーをアルファベット順にソートした上でprettyした文字列を返す。
*/
fun String.toNormalizedJson(): String {
val element = kotlinxJson.parseToJsonElement(this).normalize()
return jsonEncoder.encodeToString(element)
}
private fun JsonElement.normalize(): JsonElement {
return when (this) {
is JsonObject -> {
JsonObject(this.toSortedMap().mapValues { it.value.normalize() })
}
is JsonArray -> JsonArray(this.map { it.normalize() })
is JsonPrimitive -> this
}
}
/**
* json文字列をdeserialize後serializeし、余計なものが増えないか、必要な情報が欠落しないかの動作を確認する
* @param json 元のjson
* @param expectedObject Deserialize後の期待Object
*/
inline fun <reified T> testDeserialize(
json: String,
expectedObject: T? = null,
) {
val obj = kotlinxJson.decodeFromString<T>(json)
Assert.assertEquals(expectedObject, obj)
}
/**
* Objectをserializeし期待json文字列になるかを確認する
* @param json 元のjson
* @param expectedObject Deserialize後の期待Object
*/
inline fun <reified T> testSerialize(
obj: T,
expectedJson: String,
) {
val serialized = kotlinxJson.encodeToString(obj)
Assert.assertEquals(expectedJson.toNormalizedJson(), serialized.toNormalizedJson())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment