Soru Hamcrest koleksiyonları karşılaştırır


2 listeyi karşılaştırmaya çalışıyorum:

assertThat(actual.getList(), is(Matchers.containsInAnyOrder(expectedList)));

Ama fikir

java: no suitable method found for assertThat(java.util.List<Agent>,org.hamcrest.Matcher<java.lang.Iterable<? extends model.Agents>>)
method org.junit.Assert.<T>assertThat(T,org.hamcrest.Matcher<T>) is not applicable
  (no instance(s) of type variable(s) T exist so that argument type org.hamcrest.Matcher<java.lang.Iterable<? extends model.Agents>> conforms to formal parameter type org.hamcrest.Matcher<T>)
method org.junit.Assert.<T>assertThat(java.lang.String,T,org.hamcrest.Matcher<T>) is not applicable
  (cannot instantiate from arguments because actual and formal argument lists differ in length)

Nasıl yazmalıyım?


76
2018-02-07 10:00


Menşei




Cevaplar:


Eğer iki listenin aynı olduğunu iddia etmek istiyorsanız, Hamcrest ile bir şeyleri karıştırmayın:

assertEquals(expectedList, actual.getList());

Siparişe duyarlı bir karşılaştırma yapmayı gerçekten düşünüyorsanız, containsInAnyOrder varargs yöntemi ve değerleri doğrudan sağlayın:

assertThat(actual.getList(), containsInAnyOrder("item1", "item2"));

(Listenizin String, ziyade Agent, bu örnek için.)

Eğer aynı yöntemi bir List:

assertThat(actual.getList(), containsInAnyOrder(expectedList.toArray(new String[expectedList.size()]));

Bu olmadan, yöntemi tek bir argümanla çağırıyorsunuz ve Matcher Bu eşleşmeyi bekliyor Iterable nerede her eleman bir List. Bu, bir eşleşme için kullanılamaz List.

Yani, bir List<Agent> Birlikte Matcher<Iterable<List<Agent>>, kodunuzun denediği şey budur.


118
2018-02-07 13:21



"Eğer bir listenin içeriği ile aynı yöntemi çağırmak istiyorsanız" için +1. Ne yazık ki bunu çözemedim kendimi. Özellikle bir koleksiyon alan bir kurucu var. - Eyad Ebrahim
@Tim değil; containsInAnyOrder bunu gerektirir herşey Öğeler mevcut, böylece ilk onaylama başarısız olur. Görmek hasItems eğer kontrol etmek istersen en azından Bu öğeler mevcut. - Joe
Evet haklısın - Tim
InInnyOrder içerirseniz, önce her iki listenin de aynı boyuta sahip olduğundan emin olmalısınız. actual.getList() içermek "item1", "item3", "item2", test geçecek ve belki sadece listelenen öğeleri içerdiğinden emin olmak istiyorsan ... Bu durumda assertThat(actual.getList().size(), equalTo(2)); containsInAnyOrder'dan önce, bu şekilde her iki listenin de aynı içeriğe sahip olduğundan emin olursunuz. - Martin
@Martin'i düşünüyorsun hasItems. Ekstra kontrol burada gereksizdir. Yukarıdaki yorumu Tim'e ve ayrıca Hamcrest'in isItems'i, InAnyOrder içerdiği ve içerdiği fark nedir? - Joe


@ Joe'nun cevabına eklemek istediğim tek şey toArray() Burada parametre gereksizdir, bu nedenle aşağıdaki gibi siparişe duyarlı olmayan karşılaştırma yazabilirsiniz:

List<Long> actual = Arrays.asList(1L, 2L);
List<Long> expected = Arrays.asList(2L, 1L);
assertThat(actual, containsInAnyOrder(expected.toArray()));

33
2018-03-01 03:25



Bu bir yorum olmamalı mıydı? - Tim


@ Joe'nun cevabını tamamlamak için:

Hamcrest size bir listeyi eşleştirmek için üç ana yöntem sunar:

contains Listeyi daha fazla veya daha az elemente sahipse, siparişi hesaba katarak tüm öğeleri eşleştirmek için kontroller başarısız olur

containsInAnyOrder Tüm öğeleri eşleştirmeyi kontrol eder ve eğer liste daha fazla veya daha az eleman içeriyorsa, siparişin önemi yoktur, başarısız olur

hasItems Listede daha fazla yer varsa, belirtilen nesneler için sadece kontrol eder

hasItem Sadece bir nesne için kontrol eder, listenin daha fazla olup olmaması önemli değildir

Hepsi bir nesne ve kullanım listesi alabilir equals Karşılaştırma için yöntem veya belirtilen @borjab gibi diğer eşleştiriciler ile karıştırılabilir:

assertThat(myList , contains(allOf(hasProperty("id", is(7L)), 
                                   hasProperty("name", is("testName1")),
                                   hasProperty("description", is("testDesc1"))),
                             allOf(hasProperty("id", is(11L)), 
                                   hasProperty("name", is("testName2")),
                                   hasProperty("description", is("testDesc2")))));

http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#contains (E ...) http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#containsInAnyOrder(java.util.Collection) http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html#hasItems (T ...)


10
2018-05-17 16:40



Partiye biraz geç, ama her bir yöntem arasındaki farkların açıklaması için teşekkürler. - Marcos de Andrade


Varolan Hamcrest kütüphaneleri ile (v.2.0.0.0'dan itibaren), koleksiyonunuzda CollectionIntonyOrder Matcher'ı kullanmak için Collection.toArray () yöntemini kullanmak zorunda kalıyorsunuz. Çok güzel, org.hamcrest.Matchers'a ayrı bir yöntem olarak eklemek isterim:

public static <T> org.hamcrest.Matcher<java.lang.Iterable<? extends T>> containsInAnyOrder(Collection<T> items) {
    return org.hamcrest.collection.IsIterableContainingInAnyOrder.<T>containsInAnyOrder((T[]) items.toArray());
}

Aslında bu yöntemi özel test kütüphaneme ekledim ve test durumlarımın okunabilirliğini arttırmak için kullanıyorum (daha az verim nedeniyle).


6
2017-07-08 08:57



Güzel olan bu yardımcıyı kullanacağım. Buradaki isimlendirici mesaj daha bilgilendirici: sadece eksik olanları değil, birer birer isimleri de isimlendiriyor: liste elem1, elem2, elem99 olmalı ama elem1, elem2, ..., elem98 - iyi şanslar eksik olanı bulmak. - pihentagy


Nesne listesi için böyle bir şeye ihtiyacınız olabilir:

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
import static org.hamcrest.Matchers.is;

@Test
@SuppressWarnings("unchecked")
public void test_returnsList(){

    arrange();

    List<MyBean> myList = act();

    assertThat(myList , contains(allOf(hasProperty("id",          is(7L)), 
                                       hasProperty("name",        is("testName1")),
                                       hasProperty("description", is("testDesc1"))),
                                 allOf(hasProperty("id",          is(11L)), 
                                       hasProperty("name",        is("testName2")),
                                       hasProperty("description", is("testDesc2")))));
}

kullanım containsInAnyOrder Nesnelerin sırasını kontrol etmek istemiyorsanız.

Not; Eklenen uyarılardan kaçınmak için herhangi bir yardım gerçekten takdir edilecektir.


1
2018-03-09 19:00





Emin olun Objectlistenizde var equals() Onlarda tanımlanmış. Sonra

    assertThat(generatedList,is(equalTo(expectedList)));

Eserleri.


1
2017-10-12 16:47



Bu ayrıca dizilerle çalışır - Will Humphreys


Siparişi korunan kullanımla iki listeyi karşılaştırmak,

assertThat(actualList, contains("item1","item2"));

-3
2017-11-11 17:28



Bu soruya cevap vermiyor. - kamczak
Kısmen var. - rvazquezglez
@rvazquezglez Ne demek istiyorsun? Neden öyle diyorsun? Yöntemin sonucu çevremde doğru. - niaomingjian
@kamczak Kod iki listeyi karşılaştıramıyor mu? - niaomingjian
@niaomingjian Kodu kontrol ediyor actualList içindeki elemanları içerir contains Eşleştirici, eğer öğeler aynı sırada değilse başarısız olur ve eğer daha fazla eleman içeriyorsa ya da eksikse başarısız olur. - rvazquezglez