1概要

この記事では、http://jsonassert.skyscreamer.org/[JSONAssert library] – JSONデータの理解と複雑なhttp://junit.org/junit4/[JUnit]の作成に焦点を当てたライブラリーを見ていきます。そのデータを使用してテストします。


2 Mavenの依存関係

まず、Mavenの依存関係を追加しましょう。

<dependency>
    <groupId>org.skyscreamer</groupId>
    <artifactId>jsonassert</artifactId>
    <version>1.5.0</version>
</dependency>

ライブラリの最新版をチェックしてください。 。


3単純なJSONデータを扱う


3.1.

LENIENT

モードを使う

簡単なJSON文字列比較からテストを始めましょう。

String actual = "{id:123, name:\"John\"}";
JSONAssert.assertEquals(
  "{id:123,name:\"John\"}", actual, JSONCompareMode.LENIENT);

テストは期待されるJSON文字列として合格し、実際のJSON文字列は同じです。

比較

mode

LENIENT

は、実際のJSONに拡張フィールドが含まれていても、テストは合格することを意味します。

String actual = "{id:123, name:\"John\", zip:\"33025\"}";
JSONAssert.assertEquals(
  "{id:123,name:\"John\"}", actual, JSONCompareMode.LENIENT);

ご覧のとおり、

real

変数には、予期される

String

に存在しない追加のフィールド

zip

が含まれています。それでも、テストは成功します。

この概念はアプリケーション開発に役立ちます。つまり、既存のテストを中断することなく、必要に応じて追加のフィールドを返すことで、私たちのAPIは成長することができます。


3.2.

STRICT

モードを使う

前のサブセクションで説明した動作は、

STRICT

比較モードを使用して簡単に変更できます。

String actual = "{id:123,name:\"John\"}";
JSONAssert.assertNotEquals(
  "{name:\"John\"}", actual, JSONCompareMode.STRICT);

上記の例では

assertNotEquals()

の使用に注意してください。


3.3.

JSONCompareMode


の代わりに

Boolean

を使用する

比較モードは、

JSONCompareMode

ではなく

boolean

を取るオーバーロードされたメソッドを使用して定義することもできます。ここで、

LENIENT = false

および

STRICT = true

です。

String actual = "{id:123,name:\"John\",zip:\"33025\"}";
JSONAssert.assertEquals(
  "{id:123,name:\"John\"}", actual, JSONCompareMode.LENIENT);
JSONAssert.assertEquals(
  "{id:123,name:\"John\"}", actual, false);

actual = "{id:123,name:\"John\"}";
JSONAssert.assertNotEquals(
  "{name:\"John\"}", actual, JSONCompareMode.STRICT);
JSONAssert.assertNotEquals(
  "{name:\"John\"}", actual, true);


3.4. 論理比較

前述のように、

JSONAssert

はデータの論理比較を行います。これは、JSONオブジェクトを扱う際に要素の順序が問題にならないことを意味します。

String result = "{id:1,name:\"John\"}";
JSONAssert.assertEquals(
  "{name:\"John\",id:1}", result, JSONCompareMode.STRICT);
JSONAssert.assertEquals(
  "{name:\"John\",id:1}", result, JSONCompareMode.LENIENT);

厳密かどうかにかかわらず、上記のテストは両方の場合に合格します。

論理値比較のもう1つの例は、同じ値に異なるタイプを使用することによって実証できます。

JSONObject expected = new JSONObject();
JSONObject actual = new JSONObject();
expected.put("id", Integer.valueOf(12345));
actual.put("id", Double.valueOf(12345));

JSONAssert.assertEquals(expected, actual, JSONCompareMode.LENIENT);

ここで最初に注意することは、前の例で行ったように、Stringではなく

JSONObject

を使用していることです。次に、

expected



Integer

を、

actual



Double

を使用しました。両方の論理値12345が同じであるため、テストはタイプに関係なく合格します。

オブジェクト表現を入れ子にした場合でも、このライブラリはかなりうまく機能します。

String result = "{id:1,name:\"Juergen\",
  address:{city:\"Hollywood\", state:\"LA\", zip:91601}}";
JSONAssert.assertEquals("{id:1,name:\"Juergen\",
  address:{city:\"Hollywood\", state:\"LA\", zip:91601}}", result, false);


3.5. ユーザー指定メッセージを含むアサーション

すべての

assertEquals()

メソッドと

assertNotEquals()

メソッドは、最初のパラメーターとして

String

メッセージを受け取ります。このメッセージは、テストが失敗した場合に意味のあるメッセージを提供することで、テストケースにカスタマイズを提供します。

String actual = "{id:123,name:\"John\"}";
String failureMessage = "Only one field is expected: name";
try {
    JSONAssert.assertEquals(failureMessage,
      "{name:\"John\"}", actual, JSONCompareMode.STRICT);
} catch (AssertionError ae) {
    assertThat(ae.getMessage()).containsIgnoringCase(failureMessage);
}

何らかの障害が発生した場合、エラーメッセージ全体がよりわかりやすくなります。

Only one field is expected: name
Unexpected: id

最初の行はユーザー指定のメッセージであり、2行目はライブラリーによって提供される追加のメッセージです。


4 JSON配列を使った作業

JSON配列の比較規則は、JSONオブジェクトと比べて少し異なります。


4.1. 配列内の要素の順序

最初の違いは、** 配列内の要素の順序は

STRICT

比較モードで正確に同じでなければならないことです。ただし、

LENIENT

比較モードの場合、順序は関係ありません。

String result = "[Alex, Barbera, Charlie, Xavier]";
JSONAssert.assertEquals(
  "[Charlie, Alex, Xavier, Barbera]", result, JSONCompareMode.LENIENT);
JSONAssert.assertEquals(
  "[Alex, Barbera, Charlie, Xavier]", result, JSONCompareMode.STRICT);
JSONAssert.assertNotEquals(
  "[Charlie, Alex, Xavier, Barbera]", result, JSONCompareMode.STRICT);

これは、APIがソートされた要素の配列を返し、レスポンスがソートされているかどうかを確認したいシナリオでは非常に便利です。


4.2. 配列内の拡張要素

もう1つの違いは、

JSON配列を扱うときに

拡張要素を使用できないことです。

String result = "[1,2,3,4,5]";
JSONAssert.assertEquals(
  "[1,2,3,4,5]", result, JSONCompareMode.LENIENT);
JSONAssert.assertNotEquals(
  "[1,2,3]", result, JSONCompareMode.LENIENT);
JSONAssert.assertNotEquals(
  "[1,2,3,4,5,6]", result, JSONCompareMode.LENIENT);

上記の例は、

LENIENT

比較モードを使用しても、期待される配列内の項目が実際の配列内の項目と正確に一致する必要があることを明確に示しています。単一の要素であっても追加または削除すると、失敗します。


4.3. アレイ固有の操作

配列の内容をさらに検証するための他の手法もいくつかあります。

配列のサイズを確認したいとします。これは、期待値として具体的な構文を使用することによって実現できます。

String names = "{names:[Alex, Barbera, Charlie, Xavier]}";
JSONAssert.assertEquals(
  "{names:[4]}",
  names,
  new ArraySizeComparator(JSONCompareMode.LENIENT));


String


“ \ {names:[4]} ”

は、配列の予想サイズを指定します。

別の比較手法を見てみましょう。

String ratings = "{ratings:[3.2,3.5,4.1,5,1]}";
JSONAssert.assertEquals(
  "{ratings:[1,5]}",
  ratings,
  new ArraySizeComparator(JSONCompareMode.LENIENT));

上記の例は、配列内のすべての要素が[1,5](1と5の両方を含む)の値を持つ必要があることを確認します。 1未満または5より大きい値があると、上記のテストは失敗します。


5高度な比較例

我々のAPIが複数の

__id


を返し、それぞれが

Integer

値であるユースケースを考えてみましょう。これは、すべての


id


が単純な正規表現


__d

を使って検証できることを意味します。

上記の正規表現を

CustomComparator

と組み合わせて、すべての

__id


のすべての値に適用できます。いずれかの


id

__が正規表現と一致しない場合、テストは失敗します。

JSONAssert.assertEquals("{entry:{id:x}}", "{entry:{id:1, id:2}}",
  new CustomComparator(
  JSONCompareMode.STRICT,
  new Customization("entry.id",
  new RegularExpressionValueMatcher<Object>("\\d"))));

JSONAssert.assertNotEquals("{entry:{id:x}}", "{entry:{id:1, id:as}}",
  new CustomComparator(JSONCompareMode.STRICT,
  new Customization("entry.id",
  new RegularExpressionValueMatcher<Object>("\\d"))));

上記の例の“

\ {id:x}

”はプレースホルダーに過ぎません –

x

は任意のものに置き換えることができます。正規表現パターン ‘

\ d

‘が適用される場所です。

id

自体は別のフィールド

entry

内にあるため、

Customization



id

の位置を指定し、それによって

CustomComparator

は比較を実行できます。


6. 結論

この簡単な記事では、JSONAssertが役立つ可能性があるさまざまなシナリオについて説明しました。私たちは非常に単純な例から始めて、より複雑な比較に移りました。

もちろん、いつものように、ここで説明したすべての例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/libraries[over GitHub]にあります。