1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

KotestでJSON Schemaを検証する方法

Last updated at Posted at 2023-07-09

shouldEqualJson だと、検証に含めたくない keyがある場合に使用できない。
shouldEqualSpecifiedJson だと、何かしらの不具合や改修でjsonのプロパティが増えた場合にエラーにならない。
そのような場合に、shouldEqualSpecifiedJson + JSONのSchemaの検証で対応できます。

JSON Schemaを検証する方法

shouldMatchSchema を使用します。
公式ドキュメントは以下になります。
https://kotest.io/docs/assertions/json/json-overview.html

import io.kotest.assertions.json.schema.*
import io.kotest.core.spec.style.FreeSpec

class JsonSchemaTest : FreeSpec({
    this as JsonSchemaTest
    
    "ユーザプロフィールのJSON Schemaが正しいこと" {
        val jsonValue = """
            {
                "userId":1,
                "name":"山田太郎",
                "profile":{
                    "nickname":"ヤマダー",
                    "phone":"090-1111-2222"
                }
            }
        """.trimIndent()

        val userWithProfileJsonSchema = jsonSchema {
            obj {
                additionalProperties = false // 指定したプロパティ以外が存在する場合にエラーにする
                integer("userId")
                string("name")
                obj("profile") {
                    additionalProperties = false
                    string("nickname")
                    string("phone")
                }
            }
        }
        
        jsonValue shouldMatchSchema userWithProfileJsonSchema
    }
})

一部のSchemaを共通化する方法

以下のような2つの形式のJSONがあります。

{
	"userId": 1,
	"name": "山田太郎",
	"profile": {
		"nickname": "ヤマダー",
		"phone": "090-1111-2222"
	}
}
{
	"userId": 1,
	"name": "山田太郎",
	"hobby": {
		"sports": "baseball"
	}
}

その場合に、userId、nameのSchemaを共通化する方法です。
JsonSchema.JsonObjectBuilderの拡張関数を作成することで可能です。

import io.kotest.assertions.json.schema.*
import io.kotest.core.spec.style.FreeSpec

class JsonSchemaTest : FreeSpec({
    this as JsonSchemaTest

    "ユーザプロフィールのjson schemaが正しいこと" {
        val jsonValue = """
            {
                "userId":1,
                "name":"山田太郎",
                "profile":{
                    "nickname":"ヤマダー",
                    "phone":"090-1111-2222"
                }
            }
        """.trimIndent()

        val userWithProfileJsonSchema = jsonSchema {
            obj {
                additionalProperties = false
                basicInfo() // 共通化した拡張関数を呼ぶ
                obj("profile") {
                    additionalProperties = false
                    string("nickname")
                    string("phone")
                }
            }
        }

        jsonValue shouldMatchSchema userWithProfileJsonSchema
    }

    "ユーザ趣味のjson schemaが正しいこと" {
        val jsonValue = """
            {
                "userId":1,
                "name":"山田太郎",
                "hobby":{
                    "sports":"baseball"
                }
            }
        """.trimIndent()

        val userWithHobbyJsonSchema = jsonSchema {
            obj {
                additionalProperties = false
                basicInfo()
                obj("hobby") {
                    additionalProperties = false
                    string("sports")
                }
            }
        }

        jsonValue shouldMatchSchema userWithHobbyJsonSchema
    }
}) {
    fun JsonSchema.JsonObjectBuilder.basicInfo() {
        integer("userId")
        string("name")
    }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?