2013-03-25 14 views
31

与えられたコレクションに所定の順序でアイテムが含まれている場合、ハムクレストを使用してチェックする方法?私はhasItemsを試しましたが、単にその順序を無視します。ハムクレストを使用してコレクションに所定の順序でアイテムが含まれているかどうかを確認する方法

List<String> list = Arrays.asList("foo", "bar", "boo"); 

assertThat(list, hasItems("foo", "boo")); 

//I want this to fail, because the order is different than in "list" 
assertThat(list, hasItems("boo", "foo")); 
+1

受け入れられた回答を変更することを検討してください。通常、マッチャーを検索する際には、APIに既に含まれているものを優先し、カスタムマッチャーを避けられないケースに置き換えます。 – acdcjunior

+0

あなたは正しいです!ありがとう –

+1

受け入れられた答えは質問に答えません。質問は、期待されたアイテムが実際のリスト内の指定された順序で含まれているかどうかをチェックするだけのマッチャを要求しますが、これらはすべて実際のアイテムではありません。 'Matchers.contains'メソッドは、リストに期待されるアイテムが正確に含まれているかどうかをチェックします。 –

答えて

40

代わりcontainsマッチャーを使用することができますが、あなたはおそらくHamcrestの最新バージョンを使用する必要があります。そのメソッドは順序をチェックします。

assertThat(list, contains("foo", "boo")); 

ご注文が問題でない場合は、containsInAnyOrderもお試しください。

contains正規表現エンジンのコードです:あなたはカスタムマッチャー、この

のようなもの
class ListMatcher extends BaseMatcher { 
    String[] items; 

    ListMatcher(String... items) { 
     this.items = items; 
    } 

    @Override 
    public boolean matches(Object item) { 
     List list = (List) (item); 
     int l = -1; 
     for (String s : items) { 
      int i = list.indexOf(s); 
      if (i == -1 || i < l) { 
       return false; 
      } 
      l = i; 
     } 
     return true; 
    } 

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

@Test 
public void test1() { 
    List<String> list = Arrays.asList("foo", "bar", "boo"); 
    Assert.assertThat(list, new ListMatcher("foo", "boo")); 
    Assert.assertThat(list, new ListMatcher("boo", "foo")); 
} 
+1

+1はい、最新のJUnitとHamcrestにアップデートしますが、 'contains'はしばらくありました。 –

+1

Hamcrestのどのバージョン? java.lang.AssertionError: 期待される:["foo"、 "boo"] が含まれている反復可能ですが、一致しない: "bar" –

+1

解決策は指定されたサブセットに対しては機能しません。 contains-Matcherは予想される項目配列に指定されていない余分な項目で失敗するため、結果リスト。 – vvursT

3

。それはまだだから私は私自身のIsIterableContainingInRelativeOrder、およびsubmitted it as a patchを書いた

Expected: iterable containing ["foo", "boo"] but: Not matched: "bar" 

を言って、失敗しました。

+0

あなたのコードは真実を返すことはありません - 私はそれを修正しました。 –

+2

OMG。このマッチャーは醜くバグがあります。 TypeSafeMatcherを拡張する必要があります。matches()メソッドのitemのインスタンスを少なくともチェックするか、現在ClassCastExecptionを取得できます。現在のところ、String型のみで動作するため、汎用型でなければなりません。そしてnullを処理する必要があります。そして、matches()にはO(n^2)の複雑さがあります。そして... – Marek

1

受け入れ答えは私のために働いていませんを実装する必要が

public static <E> Matcher<Iterable<? extends E>> contains(List<Matcher<? super E>> itemMatchers) 
    { 
    return IsIterableContainingInOrder.contains(itemMatchers); 
    } 
-1

Iは、厳密な順序の例を有するセクションのhttp://www.baeldung.com/hamcrest-collections-arrays

ルックで解決策を見つけました。

List<String> collection = Lists.newArrayList("ab", "cd", "ef"); 
assertThat(collection, contains("ab", "cd", "ef")); 

は、基本的には、thaのコレクションはあなたがHamcrestのcontainsInRelativeOrderメソッドを使用することができます期待(与えられた)ために、項目を含むチェックするにはマッチャー(org.hamcrest.Matchers.contains

+3

ようこそスタックオーバーフロー。ここでは、答えに重要なコード部分を含める方がよいでしょう。 – AliLotfi

1

が含まれて使用する必要があります。 javadocツールから

:JavaのHamcrest 2.0.0.0の実際

Creates a matcher for Iterable's that matches when a single pass over the examined Iterable yields a series of items, that contains items logically equal to the corresponding item in the specified items, in the same relative order For example: assertThat(Arrays.asList("a", "b", "c", "d", "e"), containsInRelativeOrder("b", "d")).

これが役に立ちます。

関連する問題