🗂

MockMvcのテストでandExpect(jsonPath())を利用して検証する

に公開

jsonPathとは?

JSONドキュメントから特定のデータを抽出するためのクエリ言語です。
REST APIのレスポンスの検証や、データ処理において非常に有用です。

よく使うJsonPathの構文

表現 意味
$ ルート全体(JSON全体)
$.title ルート直下のtitleを参照
$.data[0].id 配列dataの最初の要素のid
$.data[*].title data配列の全要素のtitleを取得
$.data.length() ルート直下のdataの長さ

演算子

演算子 説明
$ すべてのパス式の始まり。ルートノードを表す記号。
@ 現在処理中のノードを指し、フィルター条件内で使用される。
* ワイルドカード。すべての要素と一致。
. ドット表記による子ノードのアクセス。
[start:end] 配列のスライス演算子。指定範囲の要素を取得。
[?( )] フィルター式。条件に一致するすべての要素を取得。例:book[?(@.price == 49.99)]

JsonPath関数

JsonPathは、パス式の末尾に付加して実行できる各種関数を提供しています。

関数名 説明 戻り値の型
min() 数値配列の最小値を返す Double
max() 数値配列の最大値を返す Double
avg() 数値配列の平均値を返す Double
stddev() 数値配列の標準偏差を返す Double
length() 配列の長さを返す Integer
sum() 数値配列の合計を返す Double
keys() プロパティのキー一覧を返す Set
concat() 指定のパラメータと連結された新しいオブジェクトを返す パラメータと同じ型
append() 出力配列に新しい要素を追加する パラメータと同じ型

JsonPathフィルター

特定の条件に基づいて要素を抽出するためのフィルター構文です。

演算子 説明
== 左辺と右辺の値が同一かどうかを比較(※ 文字列の '1' と 数値の 1 は異なる)
!= 左辺と右辺の値が異なるかどうかを比較
< 左辺が右辺より小さい場合
<= 左辺が右辺以下の場合
> 左辺が右辺より大きい場合
>= 左辺が右辺以上の場合
=~ 左辺が右辺で定義された正規表現に一致する場合
in 左辺が右辺で定義された配列に含まれている場合
nin 左辺が右辺で定義された配列に含まれていない場合
subsetof 左辺のすべての値が右辺の配列に含まれている場合
anyof 左辺のいずれかの値が右辺の配列に含まれている場合
noneof 左辺のいずれの値も右辺の配列に含まれていない場合
size 左辺のサイズ(文字列または配列)が右辺と同じ場合
empty 左辺の値が空である場合

実用例:一覧取得APIのテスト

mockMvc.perform(get("/posts"))
    .andExpect(status().isOk())
    .andExpect(jsonPath("$.length()").value(5))                          // 配列の要素数が5であることを検証
    .andExpect(jsonPath("$[0].title").exists())                          // 最初の要素の title フィールドが存在することを検証
    .andExpect(jsonPath("$[0].title").value("ブログタイトル1"))          // 最初の要素の title が「ブログタイトル1」であることを検証
    .andExpect(jsonPath("$[?(@.title =~ /.*ブログ.*/)]").exists())       // title に「ブログ」を含む要素が存在することを検証(正規表現)
    .andExpect(jsonPath("$[?(@.title == 'ブログタイトル5')]").exists())  // title が「ブログタイトル5」である要素が存在することを検証
    .andExpect(jsonPath("$[4].content").isNotEmpty())                    // 5番目の要素の content が空でないことを検証
    .andExpect(jsonPath("$[99].content").doesNotExist())                // インデックス99の content が存在しないことを検証
    .andExpect(jsonPath("$[?(@.id > 0)]").exists());                     // id が0より大きい要素が存在することを検証

参考リンク:公式ドキュメント

Discussion