Hamcrest Number Matcherを使う

Hamcrest番号マッチャーの使用

1. 概要

Hamcrest provides static matchers to help make unit test assertions simpler and more legible.利用可能なマッチャーhereのいくつかの探索を開始できます。

この記事では、数値に関連するマッチャーについて詳しく説明します。

2. セットアップ

Hamcrestを取得するには、次のMaven依存関係をpom.xmlに追加する必要があります。


    org.hamcrest
    java-hamcrest
    2.0.0.0

最新のHamcrestバージョンはMaven Centralにあります。

3. 近接マッチャー

ここで見ていく最初のマッチャーのセットは、check if some element is close to a value +/- an errorのものです。

もっと正式に:

value - error <= element <= value + error

上記の比較が真の場合、アサーションはパスします。

実際の動作を見てみましょう。

3.1. isCloseDoubleの値

actual.という名前のdouble変数に数値が格納されているとします。そして、actualが1 +/- 0.5に近いかどうかをテストしたいとします。

あれは:

1 - 0.5 <= actual <= 1 + 0.5
    0.5 <= actual <= 1.5

次に、isCloseマッチャーを使用して単体テストを作成しましょう。

@Test
public void givenADouble_whenCloseTo_thenCorrect() {
    double actual = 1.3;
    double operand = 1;
    double error = 0.5;

    assertThat(actual, closeTo(operand, error));
}

1.3は0.5〜1.5であるため、テストに合格します。 同様に、否定的なシナリオをテストできます。

@Test
public void givenADouble_whenNotCloseTo_thenCorrect() {
    double actual = 1.6;
    double operand = 1;
    double error = 0.5;

    assertThat(actual, not(closeTo(operand, error)));
}

それでは、異なるタイプの変数を使用した同様の状況を見てみましょう。

3.2. isCloseBigDecimalの値

isClose is overloaded and can be used same as with double values, but with BigDecimal objects

@Test
public void givenABigDecimal_whenCloseTo_thenCorrect() {
    BigDecimal actual = new BigDecimal("1.0003");
    BigDecimal operand = new BigDecimal("1");
    BigDecimal error = new BigDecimal("0.0005");

    assertThat(actual, is(closeTo(operand, error)));
}

@Test
public void givenABigDecimal_whenNotCloseTo_thenCorrect() {
    BigDecimal actual = new BigDecimal("1.0006");
    BigDecimal operand = new BigDecimal("1");
    BigDecimal error = new BigDecimal("0.0005");

    assertThat(actual, is(not(closeTo(operand, error))));
}

the is matcher only decorates other matchers without adding extra logicに注意してください。 アサーション全体を読みやすくするだけです。

近接マッチャーについては以上です。 次に、オーダーマッチャーについて見ていきます。

4. オーダーマッチャー

その名前が示すように、these matchers help make assertions regarding the order.

それらの5つがあります。

  • compareEqualTo

  • より大きい

  • 以上

  • 未満

  • lessThanOrEqualTo

それらはほとんど自明ですが、いくつかの例を見てみましょう。

4.1. Integer Valuesでマッチャーを注文する

最も一般的なシナリオはusing these matchers with numbersです。

それでは、先に進んでいくつかのテストを作成しましょう。

@Test
public void given5_whenComparesEqualTo5_thenCorrect() {
    Integer five = 5;

    assertThat(five, comparesEqualTo(five));
}

@Test
public void given5_whenNotComparesEqualTo7_thenCorrect() {
    Integer seven = 7;
    Integer five = 5;

    assertThat(five, not(comparesEqualTo(seven)));
}

@Test
public void given7_whenGreaterThan5_thenCorrect() {
    Integer seven = 7;
    Integer five = 5;

    assertThat(seven, is(greaterThan(five)));
}

@Test
public void given7_whenGreaterThanOrEqualTo5_thenCorrect() {
    Integer seven = 7;
    Integer five = 5;

    assertThat(seven, is(greaterThanOrEqualTo(five)));
}

@Test
public void given5_whenGreaterThanOrEqualTo5_thenCorrect() {
    Integer five = 5;

    assertThat(five, is(greaterThanOrEqualTo(five)));
}

@Test
public void given3_whenLessThan5_thenCorrect() {
   Integer three = 3;
   Integer five = 5;

   assertThat(three, is(lessThan(five)));
}

@Test
public void given3_whenLessThanOrEqualTo5_thenCorrect() {
   Integer three = 3;
   Integer five = 5;

   assertThat(three, is(lessThanOrEqualTo(five)));
}

@Test
public void given5_whenLessThanOrEqualTo5_thenCorrect() {
   Integer five = 5;

   assertThat(five, is(lessThanOrEqualTo(five)));
}

理にかなっているよね? 述語が表明していることを理解するのがどれほど簡単であるかに注意してください。

4.2. String値のオーダーマッチャー

数値を比較することは完全に理にかなっていますが、多くの場合、他の種類の要素を比較すると便利です。 そのため、order matchers can be applied to any class that implements the Comparable interfaceです。

Strings:の例をいくつか見てみましょう

@Test
public void givenBenjamin_whenGreaterThanAmanda_thenCorrect() {
    String amanda = "Amanda";
    String benjamin = "Benjamin";

    assertThat(benjamin, is(greaterThan(amanda)));
}

@Test
public void givenAmanda_whenLessThanBenajmin_thenCorrect() {
    String amanda = "Amanda";
    String benjamin = "Benjamin";

    assertThat(amanda, is(lessThan(benjamin)));
}

Stringは、ComparableインターフェイスからcompareToメソッドにアルファベット順を実装します。

ですから、「アマンダ」という言葉が「ベンジャミン」という言葉の前に来るのは理にかなっています。

4.3. LocalDate値のオーダーマッチャー

Stringsと同じように、日付を比較できます。 上で作成したのと同じ例を見てみましょうが、LocalDateオブジェクトを使用しています。

@Test
public void givenToday_whenGreaterThanYesterday_thenCorrect() {
    LocalDate today = LocalDate.now();
    LocalDate yesterday = today.minusDays(1);

    assertThat(today, is(greaterThan(yesterday)));
}

@Test
public void givenToday_whenLessThanTomorrow_thenCorrect() {
    LocalDate today = LocalDate.now();
    LocalDate tomorrow = today.plusDays(1);

    assertThat(today, is(lessThan(tomorrow)));
}

ステートメントassertThat(today, is(lessThan(tomorrow)))が通常の英語に近いのはとてもうれしいことです。

4.4. カスタムクラスesのマッチャーを注文する

したがって、独自のクラスを作成してComparable?を実装してみませんか。そうすれば、we can leverage order matchers to be used with custom order rulesになります。

PersonBeanを作成することから始めましょう。

public class Person {
    String name;
    int age;

    // standard constructor, getters and setters
}

それでは、Comparableを実装しましょう。

public class Person implements Comparable {

    // ...

    @Override
    public int compareTo(Person o) {
        if (this.age == o.getAge()) return 0;
        if (this.age > o.getAge()) return 1;
        else return -1;
    }
}

compareToの実装では、2人を年齢で比較しています。 次に、いくつかの新しいテストを作成しましょう。

@Test
public void givenAmanda_whenOlderThanBenjamin_thenCorrect() {
    Person amanda = new Person("Amanda", 20);
    Person benjamin = new Person("Benjamin", 18);

    assertThat(amanda, is(greaterThan(benjamin)));
}

@Test
public void
givenBenjamin_whenYoungerThanAmanda_thenCorrect() {
    Person amanda = new Person("Amanda", 20);
    Person benjamin = new Person("Benjamin", 18);

    assertThat(benjamin, is(lessThan(amanda)));
}

マッチャーは、compareToロジックに基づいて機能するようになります。

5. NaNマッチャー

Hamcrestはone extra number matcher to define if a number is actually, not a numberを提供します:

@Test
public void givenNaN_whenIsNotANumber_thenCorrect() {
    double zero = 0d;

    assertThat(zero / zero, is(notANumber()));
}

6. 結論

ご覧のとおり、number matchers are very useful to simplify common assertionsです。

さらに、一般的なハムクレストマッチャーはself-explanatory and easy to readです。

これらすべてに加えて、マッチャーとカスタム比較ロジックを組み合わせる機能により、それらはほとんどのプロジェクトで強力なツールとなります。

この記事の例の完全な実装は、over on GitHubにあります。