2013-11-25 13 views
18

私は最近Hamcrestライブラリを使っていくつかのテストを書いてきましたが、かなり成功しましたが、もっと複雑なことをする必要があります。私はマップ内のアイテムのプロパティを調べ、検証する必要があります。私の生産コードは次のようになります:Hamcrestを使用してマップ項目を検査する方法

Map<String, List<MyItem>> map = new HashMap<String, List<MyItem>>(); 
    map.put("one", Arrays.asList(new MyItem("One"))); 
    map.put("two", Arrays.asList(new MyItem("Two"))); 
    map.put("three", Arrays.asList(new MyItem("Three"))); 

次のようなテストコードを書いてみたいが、コンパイルはしない。ハムクレストのhasEntryは型がパラメータ化されているように見えますが、hasItemとhasPropertyはObjectだけを必要とします。

assertThat(map, Matchers.<String, List<MyItem>>hasEntry("one", hasItem(hasProperty("name", is("One"))))); 

私のIDE(Eclipseの)は、このエラーメッセージを与えている:タイプMatchersのパラメータ化方法<String, List<HamcrestTest.MyItem>>hasEntry(String, List<HamcrestTest.MyItem>)は、引数(String, Matcher<Iterable<? super Object>>)には適用されません。私はEclipseが混乱していると思うのは、hasEntryメソッドを使いたいのですが、それはではなくhasEntry(org.hamcrest.Matcher<? super K> keyMatcher, org.hamcrest.Matcher<? super V> valueMatcher)でなければなりません。

私はあきらめて地図からアイテムを手に入れ、各プロパティを手動で調べるべきですか?よりクリーンな方法がありますか?

答えて

21

YouuはちょうどcontainsまたはcontainsInAnyOrderを使用できます。確かに、あなたはListそのようにすべての項目を一覧表示する必要がありますが、それはhasItemよりもクリーンに動作します:

@SuppressWarnings("unchecked") 
@Test 
public void mapTest() { 
    Map<String, List<MyItem>> map = new HashMap<String, List<MyItem>>(); 
    map.put("one", asList(new MyItem("1"), new MyItem("one"))); 

    assertThat(map, hasEntry(is("one"), 
          containsInAnyOrder(hasProperty("name", is("one")), 
               hasProperty("name", is("1"))))); 
} 
+1

'hasEntry'が必要な' Matcher > ' –

+0

@ JohnBの代わりに' Matcher > 'を返すので、これはコンパイル時のエラーを解決するとは思わない:それを信じるかどうかは分かりませんが、試してみました。 – t0mppa

+1

悪い場合があります。いいですよ。 –

4

だからあなたはこれを試してみてください、これは簡単にするために...

assertThat((Object)map, (Matcher)Matchers.hasEntry("one", hasItem(hasProperty("name", is("One"))))); 

警告が、ありません、コンパイルエラーになります生のタイプに行くこともできます。過去にこのトリックを使用していたのであれば、コンパイラのためにすべてのキャスティングを行うことを心配したくはありません。

また、ItIterableContainingInOrder.containingInOrder(new MyItem("One")))の使用を検討することもできます。これによりリスト全体が確認され、MyItemequalsを実装する場合は、テストで反射を使用しません。

1

@のt0mppaはこのためHamcrestのcontainscontainsInAnyOrderを使用する方法の良い例を提供していませんでしたので、

Map<Integer, String> columns = new HashMap<Integer, String>(); 
columns.put(1, "ID"); 
columns.put(2, "Title"); 
columns.put(3, "Description"); 

assertThat(columns.values(), contains("ID", "Title", "Description")); // passes 
assertThat(columns.values(), contains("ID", "Description", "Title")); // fails 
assertThat(columns.values(), containsInAnyOrder("ID", "Description", "Title")); // passes 

hasItemhasItemsとは対照的に、あなたはと照合されますすべての値の完全なリストとそれらを提供する場合、これらはのみ動作すること:、ここであなたを始めるために少し何かがあります。詳細については、Hamcrestのjavadocsを参照してください。

関連する問題