web-dev-qa-db-ja.com

このコードがHamcrestのhasItemsを使用しようとしないのはなぜですか?

なぜこれがコンパイルされないのですか?

import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.hasItems;

ArrayList<Integer> actual = new ArrayList<Integer>();
ArrayList<Integer> expected = new ArrayList<Integer>();
actual.add(1);
expected.add(2);
assertThat(actual, hasItems(expected));

コメントからコピーされたエラー:

cannot find symbol method assertThat(Java.util.ArrayList<Java.lang.Integer>, org.hamcreset.Matcher<Java.lang.Iterable<Java.util.ArrayList<Java.lang.Integer>>>)
55
ripper234

自分で修正しようとしてこの投稿に出くわしました。解決するのに十分な情報を提供してください。

HasItemsからの戻り値を(生の)マッチャーにキャストすることで、コンパイラーを説得するのに十分なだけコンパイラーに与えることができます。例えば:

ArrayList<Integer> actual = new ArrayList<Integer>();
ArrayList<Integer> expected = new ArrayList<Integer>();
actual.add(1);
expected.add(2);
assertThat(actual, (Matcher) hasItems(expected));

他の誰かがまだ苦しんでいる場合に備えて...

編集して追加:賛成票にもかかわらず、以下のArendが指摘しているように、この答えは間違っています。 正しい答えは、hamcrestが期待しているように、期待値を整数の配列に変えることです:

    ArrayList<Integer> actual = new ArrayList<Integer>();
    ArrayList<Integer> expected = new ArrayList<Integer>();
    actual.add(1);
    expected.add(2);
    assertThat(actual, hasItems(expected.toArray(new Integer[expected.size()])));
53
Clive Evans

hasItemsは、コレクションにいくつかのアイテムが含まれていることをチェックします。2つのコレクションが等しいことではなく、そのために通常の等価アサーションを使用します。したがって、assertEquals(a、b)またはassertThatの使用

import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.is;

ArrayList<Integer> actual = new ArrayList<Integer>();
ArrayList<Integer> expected = new ArrayList<Integer>();
actual.add(1);
expected.add(2);
assertThat(actual, is(expected));

あるいは、包含マッチャーを使用します。これは、イテラブルに特定の順序でアイテムが含まれていることを確認します

import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.contains;

ArrayList<Integer> actual = new ArrayList<Integer>();
actual.add(1);
actual.add(2);
assertThat(actual, contains(1, 2)); // passes
assertThat(actual, contains(3, 4)); // fails

順序を気にしない場合は、代わりにcontainsInAnyOrderを使用してください。

22
Dan Godfrey

ArrayList<Integer>intを比較しています。正しい比較は次のとおりです。

...
assertThat(actual, hasItem(2));

-編集-

申し訳ありませんが、間違って読みました。とにかく、あなたが望むhasItemsの署名は次のとおりです。

public static <T> org.hamcrest.Matcher<Java.lang.Iterable<T>> hasItems(T... elements)

つまり、可変数の引数を受け入れます。ここで推測するだけで、ArrayList<T>に互換性があるかどうかはわかりません。コンマが点在する予想リストから各アイテムを送信してみてください。

assertThat(actual, hasItems(2,4,1,5,6));

-編集2-

ここに私のコメントを貼り付けるだけで、Hamcrestを使用せずに、あなたが望むものと同等の表現があります:

assertTrue(actual.containsAll(expected));
12
freitass

試して

assertThat(actual, hasItems(expected.toArray(new Integer[0])));

マッチャーの署名を満たすため。周りにEclipseがないため、これは機能しない可能性があります。

3
Robert Munteanu

JUnitのhamcrestを新しいバージョンに置き換えようとすると、このエラーが発生する可能性があります。たとえば、hamcrest 1.3とともにjunit-depを使用するには、jUnitの代わりにhamcrestのassertThatを使用する必要があります。

解決策は使用することです

import static org.hamcrest.MatcherAssert.assertThat;

の代わりに

import static org.junit.Assert.assertThat;

2
Mika

私はちょうど同じ問題に遭遇し、次のトリックが私のために働いた:

  • つかいます import static org.hamcrest.Matchers.hasItems
  • クラスパス内のjunitの前にhamcrestライブラリがある(ビルドパス->順序とエクスポート)
2
Zsolt

このエラーメッセージは、javacコンパイラによって生成されたもののように見えます。私は過去に、hamcrestを使用して記述されたコードがjavacでコンパイルできないことを発見しました。たとえば、Eclipseコンパイラーで同じコードをコンパイルできます。

Hamcrestのジェネリックは、javacが処理できないジェネリックのコーナーケースを行使していると思います。

2
skaffman

これらの場合、コードはEclipseでコンパイルされるが、javacがエラーを表示する場合、明示的に型パラメーターを提供することでhamcrestを助けてください。 Matchers.hasItem()

1
miluch
ArrayList<Integer> expected = new ArrayList<Integer>();
expected.add(1);
expected.add(2);
hasItems(expected);

hasItems(T..t)は、コンパイラによって次のように拡張されています。

hasItems(new ArrayList<Integer>[]{expected});

ArrayListを含む単一の要素配列を渡します。 ArrayListを配列に変更すると、コードは機能します。

Integer[] expected = new Integer[]{1, 2};
hasItems(expected);

これは次のように拡張されます。

hasItems(1, 2);
0
Matthew