Hamcrest संग्रह की तुलना करता है


114

मैं 2 सूचियों की तुलना करने की कोशिश कर रहा हूं:

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

लेकिन विचार

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)

मुझे इसे कैसे लिखना चाहिए?

जवाबों:


161

यदि आप यह दावा करना चाहते हैं कि दो सूचियाँ समान हैं, तो Hamcrest के साथ चीजों को जटिल न करें:

assertEquals(expectedList, actual.getList());

यदि आप वास्तव में आदेश-असंवेदनशील तुलना करने का इरादा रखते हैं, तो आप containsInAnyOrderवैरगेज विधि को कॉल कर सकते हैं और सीधे मान प्रदान कर सकते हैं:

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

(यह मानते हुए कि आपकी सूची Stringइसके बजाय हैAgent इस उदाहरण के , की है।)

यदि आप वास्तव में उसी विधि की सामग्री के साथ कॉल करना चाहते हैं List:

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

इसके बिना, आप विधि को एक एकल तर्क के साथ बुला रहे हैं और एक Matcherऐसा निर्माण करने की अपेक्षा करते हैं Iterableजहां प्रत्येक तत्व एक है List। यह एक मैच के लिए इस्तेमाल नहीं किया जा सकता है List

यही है, आप एक के List<Agent>साथ मेल नहीं कर सकते हैं Matcher<Iterable<List<Agent>>, जो आपके कोड का प्रयास कर रहा है।


+1 के लिए "यदि आप वास्तव में सूची की सामग्री के साथ उसी विधि को कॉल करना चाहते हैं"। अफसोस की बात है कि मैं खुद को हल नहीं कर सका। विशेष रूप से एक रचनाकार है जो एक संग्रह में लेता है।
Eyad इब्राहिम

3
@ टिम बिल्कुल नहीं; containsInAnyOrderइसके लिए आवश्यक है कि सभी तत्व मौजूद हों, ताकि पहला जोर विफल हो जाए। देखें hasItemsकि क्या आप जांचना चाहते हैं कि कम से कम वे तत्व मौजूद हैं या नहीं।
जो

4
यदि आप इसमें शामिल हैं InAOOder, तो आपको पहले यह सुनिश्चित करना चाहिए कि दोनों सूचियों का आकार समान है ... यदि actual.getList()ऐसा होता है "item1", "item3", "item2", तो परीक्षण पास हो जाएगा और शायद आप यह सुनिश्चित करना चाहते हैं कि इसमें केवल सूचीबद्ध आइटम शामिल हों ... उस स्थिति में आप उपयोग कर सकते हैं assertThat(actual.getList().size(), equalTo(2));इसमें शामिल है InAAOOder, इससे पहले कि आप सुनिश्चित करें कि दोनों सूचियों में समान सामग्री है।
मार्टिन

1
@ मैं आप के बारे में सोच रहा हूँ hasItems। यहां अतिरिक्त जांच अनावश्यक है। ऊपर टिम को टिप्पणी देखें, और यह भी कि हैमरेस्ट के पास क्या है, इसमें शामिल हैं और इसमें शामिल हैं?
जो

1
Kotlin उपयोगकर्ता : *expectedList.toTypedArray()किसी सरणी को varargs करते समय स्प्रेड ऑपरेटर ( ) जोड़ना न भूलें !
जेम्स बोमन

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

@ जो के उत्तर के अनावश्यक संस्करण के बिना छोटा संस्करण।


28

@ जो के उत्तर के पूरक के लिए:

हैमरेस्ट आपको सूची से मिलान करने के लिए तीन मुख्य तरीके प्रदान करता है:

contains आदेश की गिनती करने वाले सभी तत्वों के मिलान के लिए चेक, यदि सूची में कम या ज्यादा तत्व हैं, तो यह विफल हो जाएगा

containsInAnyOrder सभी तत्वों के मिलान के लिए जाँच की जाती है और यह क्रम से कोई फर्क नहीं पड़ता, अगर सूची में कम या ज्यादा तत्व हैं, तो यह विफल हो जाएगा

hasItems सूची में अधिक होने पर केवल निर्दिष्ट ऑब्जेक्ट्स के लिए चेक नहीं करता है

hasItem सिर्फ एक वस्तु के लिए जाँच करता है अगर सूची अधिक है तो इससे कोई फर्क नहीं पड़ता

उनमें से सभी वस्तुओं की एक सूची प्राप्त कर सकते हैं और equalsतुलना के लिए विधि का उपयोग कर सकते हैं या अन्य मेलबॉर्स के साथ मिश्रित हो सकते हैं जैसे @borjab का उल्लेख किया गया है:

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/Java Hamcrest/javadoc/1.3/org/hamcrest/Matchers.html#contains (E ...) http://hamcrest.org/Java Hamcrest/javadoc/1.3-org/hamcrest/Matchers.html #containsInAnyOrder (java.util.Collection) http://hamcrest.org/Java Hamcrest/javadoc/1.3/org/hamcrest/Matchers.html#hasItems ( T ...)


पार्टी के लिए थोड़ा देर से, लेकिन प्रत्येक विधि के बीच अंतर के वर्णन के लिए धन्यवाद।
मार्कोस डी एंड्रेड

मामले की सूची की वस्तुओं में महान निर्णय आदिम प्रकार के नहीं हैं।
स्टानिस्लाव त्सेपा ३१'१

क्या ऐसा करने का एक सुरक्षित तरीका है?
andresp

15

मौजूदा Hamcrest पुस्तकालयों (v.2.0.0.0 के रूप में) के साथ आप संग्रह में उपयोग करने के लिए मजबूर हैं। Array () विधि आपके संग्रह में InInAnyOrder मिलान का उपयोग करने के लिए। सुदूर अच्छे ने इसे org.hamcrest.Matchers के लिए एक अलग विधि के रूप में जोड़ा जाएगा:

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

वास्तव में मैंने अपने कस्टम टेस्ट लाइब्रेरी में इस पद्धति को जोड़ना समाप्त कर दिया और इसका उपयोग अपने परीक्षण मामलों की पठनीयता (कम वाचालता के कारण) को बढ़ाने के लिए किया।


2
अच्छा लगा, मैं इस सहायक का उपयोग करूंगा। मुखर संदेश यहां अधिक जानकारीपूर्ण है: इसमें गायब वस्तुओं का नाम एक-एक करके दिया गया है, न कि केवल सूची: एलएम 1, एलएम 2, .. एलएम 99 होना चाहिए, लेकिन मुझे एलएम 1, एएलएम 2, ..., एलएम 9 9 मिला - सौभाग्य लापता को ढूंढना।
pihentagy

3

सुनिश्चित करें कि Objectआपकी सूची में s ने equals()उन पर परिभाषित किया है। फिर

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

काम करता है।


1

वस्तुओं की सूची के लिए आपको कुछ इस तरह की आवश्यकता हो सकती है:

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

यदि आप ऑब्जेक्ट्स के ऑर्डर को चेक नहीं करना चाहते हैं, तो इसमेंInAnyOrder का उपयोग करें ।

PS किसी भी चेतावनी को दबाने से बचने के लिए कोई भी मदद वास्तव में सराहना की जाएगी।


-3

आदेश संरक्षित उपयोग के साथ दो सूचियों की तुलना करने के लिए,

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

इस सवाल का जवाब नहीं है।
13 से 13

यह आंशिक रूप से करता है।
rvazquezglez

@rvazquezglez तुम्हारा क्या मतलब है? तुमने ऐसा क्यों कहा? विधि का परिणाम मेरे वातावरण में सही है।
नियामिंगजियान

@niaomingjian कोड जाँच कर रहा है कि actualListइसमें माचिस के अंदर के तत्व सम्‍मिलित हैं contains, यदि तत्व समान क्रम में नहीं हैं और यह विफल हो जाएगा, यदि इसमें अधिक तत्‍व सम्‍मिलित हैं या एक लापता है।
rvazquezglez

@rvazquezglez कोड का उद्देश्य दो सूचियों में सही समानता (समान लंबाई, मान और क्रम) की जांच करना है, है ना?
niaomingjian
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.