きり丸の技術日記

技術検証したり、資格等をここに残していきます。

JestでJSONを比較する(特定の項目を無視する)

JavaでJSONを比較する記事」を職場のSlackに貼ったところ、フロントでもJSONをいい感じに比較したいという依頼が来ました。

Jsonの比較

下記のRequestBodyを比較するようにする。

const response = 
{
    "animals": [
      "gorilla",
      "human"
    ],
    "generate_date": "2020091910011234",
    "update_date": "2020092010023456"
};

完全一致を行う

Requestと完全に一致させたJsonを用意して、Jestのexpect().toEqual()を使用する。

test('完全比較', () => {
  const expected =
  {
    "animals": [
      "gorilla",
      "human"
    ],
    "generate_date": "2020091910011234",
    "update_date": "2020092010023456"
  };
  expect(response).toEqual(expected);
});

特定の項目を完全無視する

無視したい項目に対して、expect.anything()を設定します。
これで、キーが不足していた場合はエラーですが、どのような値だろうと無視して比較できます。

有効活用できる箇所:サーバー応答時間、ランダムな値等の中身に深い価値が無い場合。

test('特定の項目を完全に無視', () => {
  const expected =
  {
    "animals": [
      "gorilla",
      "human"
    ],
    "generate_date": expect.anything(),
    "update_date": expect.anything()
  };
  expect(response).toEqual(expected);
});

正規表現で特定の項目を無視する

正規表現で比較したい項目に対して、expect.stringMatching(value)を設定します。

完全に値の無視はしたくないが、もうちょっと強固に比較したい等に使用できます。

test('正規表現で特定の項目を比較', () => {
  const expected =
  {
    "animals": [
      "gorilla",
      "human"
    ],
    "generate_date": expect.stringMatching("2020091910.*"),
    "update_date": expect.stringMatching("2020091910.*") 
    // responseのupdate_dateは20200920なので、テスト失敗する
  };
  expect(response).toEqual(expected);
});

配列項目の順番は問いたくない

配列で比較するときによく使いそうです。

  • 「データの返却」はServer
  • 「データをどう表現するか。どうソートして見せるか」等はUI層

等々、責任が分かれている場合、データの順番は意識したくありません。

なので、配列の順番を意識せず、中身だけ確認したい場合はexpect.arrayContaining(array)を使用したほうが良さそうです。

ただし、こちらを使用する場合は配列のサイズも確認すべきです。
arrayContainingは「対象の配列に、対象のオブジェクトが存在するか」という確認方法です。

期待値(expect)が多い時は対象のオブジェクトが存在しないのでエラーになってくれますが、期待値の方が少ない場合はすべて満たせているので、問題にならなくなります。

余計なデータが送られてこないことも確認したほうが良いので、サイズも確認すべきでしょう。

test('順番は無視', () => {
  const expected =
  {
    // humanだけにしてもエラーにならない。
    "animals": expect.arrayContaining([
      "human",
      "gorilla"
    ]),
    "generate_date": expect.anything(),
    "update_date": expect.anything()
  };

  // arrayContainingつかうなら、サイズも見ておいたほうが良さそう
  expect(response.animals.length).toBe(2);
  expect(response).toEqual(expected);
});

終わりに

JSON (JavaScript Object Notation)って名前ですから、Javascriptと親和性高いだろう。
そう考えてはいましたが、Jestだけで簡単に比較できるとは思いませんでした。

Javaの場合は、skyscreamer.JSONAssertとかJUnitと異なる別ライブラリを使う必要があったので、JSでも別ライブラリが必要かと考えてました。

Jestは日本語の公式ページもあるので、ぜひ参考にしてください。

私が興味なくて紹介しなかったが、有効なのもあるはずなので公式見てください。

ソースコード

requireを使って別ファイルから期待値や実値を読み込めるから、覚えると便利。

類似記事

参考記事