سؤال

أرغب في استخدام Hamcrest لتأكيد أن خريطتين متساوية ، أي أن لديهم نفس مجموعة المفاتيح التي تشير إلى نفس القيم.

أفضل تخميني الحالي هو:

assertThat( affA.entrySet(), hasItems( affB.entrySet() );

الذي يعطي:

لا تنطبق الطريقة (T ، Matcher) في النوع التأكيد على الوسائط (Set> ، Matcher >>>)

لقد بحثت أيضًا في اختلافات ContaLsall ، وبعضها الآخر المقدم من حزم Hamcrest. يمكن لأي شخص لي نقطة في الاتجاه الصحيح؟ أو هل يجب أن أكتب مطابقة مخصصة؟

هل كانت مفيدة؟

المحلول

أقصر طريقة توصلت إليها هي بيانان:

assertThat( affA.entrySet(), everyItem(isIn(affB.entrySet())));
assertThat( affB.entrySet(), everyItem(isIn(affA.entrySet())));

ولكن ربما يمكنك أيضًا القيام بذلك:

assertThat(affA.entrySet(), equalTo(affB.entrySet()));

اعتمادا على تطبيقات الخرائط.

تحديث: في الواقع هناك بيان واحد يعمل بشكل مستقل عن أنواع التجميع:

assertThat(affA.entrySet, both(everyItem(isIn(affB.entrySet()))).and(containsInAnyOrder(affB.entrySet())));

نصائح أخرى

أحيانا Map.equals() كفى. لكن في بعض الأحيان لا تعرف أنواع Mapيتم إرجاع S بواسطة الكود ضمن الاختبارات ، لذلك لا تعرف إذا .equals() سوف تقارن بشكل صحيح هذه الخريطة من النوع غير المعروف الذي تم إرجاعه بواسطة رمز مع خريطة تم إنشاؤها من قبلك. أو لا تريد ربط الكود الخاص بك مع مثل هذه الاختبارات.

بالإضافة إلى ذلك ، فإن إنشاء خريطة بشكل منفصل لمقارنة النتيجة معها ليس أنيقة للغاية:

Map<MyKey, MyValue> actual = methodUnderTest();

Map<MyKey, MyValue> expected = new HashMap<MyKey, MyValue>();
expected.put(new MyKey(1), new MyValue(10));
expected.put(new MyKey(2), new MyValue(20));
expected.put(new MyKey(3), new MyValue(30));
assertThat(actual, equalTo(expected));

أفضل استخدام الجهاز:

import static org.hamcrest.Matchers.hasEntry;

Map<MyKey, MyValue> actual = methodUnderTest();
assertThat(actual, allOf(
                      hasSize(3), // make sure there are no extra key/value pairs in map
                      hasEntry(new MyKey(1), new MyValue(10)),
                      hasEntry(new MyKey(2), new MyValue(20)),
                      hasEntry(new MyKey(3), new MyValue(30))
));

لا بد لي من تحديد hasSize() نفسي:

public static <K, V> Matcher<Map<K, V>> hasSize(final int size) {
    return new TypeSafeMatcher<Map<K, V>>() {
        @Override
        public boolean matchesSafely(Map<K, V> kvMap) {
            return kvMap.size() == size;
        }

        @Override
        public void describeTo(Description description) {
            description.appendText(" has ").appendValue(size).appendText(" key/value pairs");
        }
    };
}

وهناك متغير آخر من hasEntry() يأخذ هذا المطابقة كمعلمات بدلاً من القيم الدقيقة للمفتاح والقيمة. يمكن أن يكون هذا مفيدًا في حال كنت بحاجة إلى شيء آخر غير اختبار المساواة لكل مفتاح وقيمة.

أنا أفضل استخدام الجوافة Immutablemap. هم يساندون Map.equals() ومن السهل بناء. الحيلة الوحيدة هي تحديد معلمات النوع بشكل صريح ، لأن Hamcrest سوف يفترض ImmutableMap يكتب.

assertThat( actualValue,
            Matchers.<Map<String, String>>equalTo( ImmutableMap.of(
                "key1", "value",
                "key2", "other-value"
) ) );

خيار آخر متاح الآن هو استخدام امتداد Cirneco لهامكرست. لديها hasSameKeySet() (بالإضافة إلى المطابقة الأخرى لـ "مجموعات" الجوافة). وفقًا لمثالك ، سيكون ذلك:

assertThat(affA, hasSameKeySet(affB));

يمكنك استخدام التبعية التالية لمشروع قائم على JDK7:

<dependency>
  <groupId>it.ozimov</groupId>
  <artifactId>java7-hamcrest-matchers</artifactId>
  <version>0.7.0</version>
</dependency>

أو ما يلي إذا كنت تستخدم JDK8 أو متفوقة:

<dependency>
  <groupId>it.ozimov</groupId>
  <artifactId>java8-hamcrest-matchers</artifactId>
  <version>0.7.0</version>
</dependency>

هناك طريقة بسيطة للغاية وهي استخدام طريقة الأداة المساعدة من فئة com.google.common.collect.collect.collect.collect.collect.collect.maps.

assertThat(Maps.difference(map1,map2).areEqual(),is(true));

Hamcrest لديه الآن ملف Matcher لجمع الحجم.

org.hamcrest.collection.IsCollectionWithSize

هذا يعمل مثل السحر ولا يتطلب تأكيدين مثل الإجابة المقبولة.

assertThat( actualData.entrySet().toArray(), 
    arrayContainingInAnyOrder(expectedData.entrySet().toArray()) );

إذا كنت بحاجة إلى مقارنة مجموعة من النتائج بالتوقعات وإذا اخترت استخدامها Assertj المكتبة ، يمكنك القيام بذلك:

// put set of expected values by your test keys
Map<K, V> expectations = ...;

// for each test key get result
Map<K, V> results = expectations.keySet().stream().collect(toMap(k -> k, k -> getYourProductionResult(k)));

assertThat(results).containsAllEntriesOf(expectations);

لاحظ أن containsAllEntriesOf لا يقارن خرائط للمساواة. إذا كان رمز الإنتاج الخاص بك يعود فعليًا Map<K, V> قد ترغب في إضافة شيك للمفاتيح assertThat(results).containsOnlyKeys((K[]) expectations.keySet().toArray());

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top