55

なぜこれはコンパイルされないのですか、ああ、何をすべきですか?

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>>>)
4

9 に答える 9

55

自分で修正しようとして、この投稿に出くわしました。それを解決するのに十分な情報をくれました。

hasItems からの戻り値を (生の) Matcher にキャストすることで、コンパイルするように説得するのに十分なだけコンパイラに与えることができます。次に例を示します。

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()])));
于 2011-09-07T13:49:14.483 に答える
22

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));

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

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代わりに使用してください。

于 2009-10-28T10:53:34.597 に答える
12

と比較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 --

ここに私のコメントを貼り付けるだけで、ハムクレストを使用せずに、必要なものと同等の式があります。

assertTrue(actual.containsAll(expected));
于 2009-07-07T15:29:07.303 に答える
3

試す

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

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

于 2009-07-07T22:11:14.530 に答える
2

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

したがって、解決策は使用することです

import static org.hamcrest.MatcherAssert.assertThat;

それ以外の

import static org.junit.Assert.assertThat;

于 2013-02-25T12:37:02.117 に答える
2

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

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

于 2009-07-07T21:41:56.320 に答える
2

同じ問題に遭遇したばかりで、次のトリックがうまくいきました:

  • 使用するimport static org.hamcrest.Matchers.hasItems
  • クラスパスでjunitの前にhamcrestライブラリを用意します(ビルドパス->順序とエクスポート)
于 2011-03-10T22:01:20.833 に答える
1

コードが Eclipse でコンパイルされるが、javac がエラーを表示するこれらのケースでは、Matchers.hasItem() などの明示的な型パラメーターを指定して、hamcrest を支援してください。

于 2011-02-03T10:16:01.053 に答える
0
ArrayList<Integer> expected = new ArrayList<Integer>();
expected.add(1);
expected.add(2);
hasItems(expected);

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

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

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

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

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

hasItems(1, 2);
于 2010-10-12T17:01:29.403 に答える