1. 序章

組み込みのマッチャーだけでなく、Hamcrestはカスタムマッチャーの作成もサポートします。

このチュートリアルでは、それらを作成して使用する方法を詳しく見ていきます。 利用可能なマッチャーの概要を確認するには、この記事を参照してください。

2. カスタムマッチャーのセットアップ

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

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>java-hamcrest</artifactId>
    <version>2.0.0.0</version>
    <scope>test</scope>
</dependency>

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

3. TypeSafeMatcherのご紹介

例を始める前に、クラスTypeSafeMatcherを理解することが重要です。 このクラスを拡張して、独自のマッチャーを作成する必要があります。

TypeSafeMatcher は抽象クラスであるため、すべてのサブクラスは次のメソッドを実装する必要があります。

  • matchesSafely(T t):マッチングロジックが含まれています
  • describeTo(Description description):マッチングロジックが満たされない場合にクライアントが受け取るメッセージをカスタマイズします

最初のメソッドでわかるように、 TypeSafeMatcherはパラメーター化されているため、使用するときに型を宣言する必要があります。これがテストするオブジェクトの型になります。

次のセクションの最初の例を見て、これをより明確にしましょう。

4. onlyDigitsマッチャーの作成

最初のユースケースでは、特定の文字列に数字のみが含まれている場合にtrueを返すマッチャーを作成します。

したがって、「123」に適用されたonlyDigitstrueを返し、「hello1」と「bye」はfalseを返す必要があります。

始めましょう!

4.1. マッチャーの作成

マッチャーから始めるために、TypeSafeMatcherを拡張するクラスを作成します。

public class IsOnlyDigits extends TypeSafeMatcher<String> {
   
    @Override
    protected boolean matchesSafely(String s) {
        // ...
    }

    @Override
    public void describeTo(Description description) {
        // ...
    }
}

テストするオブジェクトはテキストであるため、次のサブクラスをパラメータ化することに注意してください。 TypeSafeMatcher クラスで弦。

これで、実装を追加する準備が整いました。

public class IsOnlyDigits extends TypeSafeMatcher<String> {

    @Override
    protected boolean matchesSafely(String s) {
        try {
            Integer.parseInt(s);
            return true;
        } catch (NumberFormatException nfe){
            return false;
        }
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("only digits");
    }
}

ご覧のとおり、 matchesSafey は、入力StringIntegerに解析しようとしています。 成功すると、trueを返します。 失敗した場合は、falseを返します。 それは私たちのユースケースにうまく反応します。

一方、 describeTo は、私たちの期待を表すテキストを添付しています。 次に、マッチャーを使用すると、これがどのように表示されるかを確認します。

マッチャーを完成させるために必要なものはあと1つだけです。それにアクセスするための静的メソッドなので、残りの組み込みマッチャーとして動作します。

したがって、次のようなものを追加します。

public static Matcher<String> onlyDigits() {
    return new IsOnlyDigits();
}

これで完了です。 次のセクションで、このマッチャーの使用方法を見てみましょう。

4.2. マッチャーの使用法

に新しいマッチャーを使用するには、テストを作成します。

@Test
public void givenAString_whenIsOnlyDigits_thenCorrect() {
    String digits = "1234";

    assertThat(digits, onlyDigits());
}

以上です。 入力Stringには数字しか含まれていないため、このテストは合格です。 もう少し読みやすくするために、他のマッチャーのラッパーとして機能するマッチャーを使用できることを覚えておいてください。

assertThat(digits, is(onlyDigits()));

最後に、同じテストを実行したが、入力が「123ABC」の場合、出力メッセージは次のようになります。

java.lang.AssertionError: 
Expected: only digits
     but: was "123ABC"

ここにdescribeToメソッドに追加したテキストが表示されます。お気づきかもしれませんが、テストで期待される内容の適切な説明を作成することが重要です。

5. divisibleBy

では、ある数値が別の数値で割り切れるかどうかを定義するマッチャーを作成したい場合はどうでしょうか。 そのシナリオでは、パラメータの1つをどこかに保存する必要があります。

それをどのように行うことができるか見てみましょう:

public class IsDivisibleBy extends TypeSafeMatcher<Integer> {

    private Integer divider;

    // constructors

    @Override
    protected boolean matchesSafely(Integer dividend) {
        if (divider == 0) {
            return false;
        }
        return ((dividend % divider) == 0);
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("divisible by " + divider);
    }

    public static Matcher<Integer> divisibleBy(Integer divider) {
        return new IsDivisibleBy(divider);
    }
}

非常に単純ですが、クラスに新しい属性を追加し、構築中に割り当てました。 次に、それをパラメーターとして静的メソッドに渡しました。

@Test
public void givenAnEvenInteger_whenDivisibleByTwo_thenCorrect() {
    Integer ten = 10;
    Integer two = 2;

    assertThat(ten,is(divisibleBy(two)));
}

@Test
public void givenAnOddInteger_whenNotDivisibleByTwo_thenCorrect() {
    Integer eleven = 11;
    Integer two = 2;

    assertThat(eleven,is(not(divisibleBy(two))));
}

以上です! すでに複数の入力を使用するマッチャーがあります!

6. 結論

Hamcrestは、開発者がアサーションを作成するときに通常対処しなければならないほとんどのユースケースをカバーするマッチャーを提供します。

さらに、特定のケースがカバーされていない場合、 Hamcrestは、特定のシナリオで使用されるカスタムマッチャーの作成もサポートします –ここで説明したようにシンプルです作成するために、それらはライブラリに含まれているものとまったく同じように使用されます。

この例の完全な実装を取得するには、GitHubプロジェクトを参照してください。