জুনিতের 2 টি তালিকার মধ্যে সমান সমান


164

JUnit পরীক্ষা মামলার তালিকার মধ্যে আমি কীভাবে সমতা দাবি করতে পারি ? সমতা তালিকার সামগ্রীর মধ্যে হওয়া উচিত।

উদাহরণ স্বরূপ:

List<String> numbers = Arrays.asList("one", "two", "three");
List<String> numbers2 = Arrays.asList("one", "two", "three");
List<String> numbers3 = Arrays.asList("one", "two", "four"); 

// numbers should be equal to numbers2
//numbers should not be equal to numbers3

5
আমি assertArrayEqualsআজকাল ব্যবহার করতে পছন্দ করি । সঙ্গে সংমিশ্রণে ব্যবহার করুন List#toArray
থিবস্টারস

@ টিবিস্টারস - আমি উত্তর হিসাবে এটি upvote করব
dfrankow

2
assertArrayEqualsআপনার তালিকা থেকে অ্যারে নেওয়া দরকার। আপনি তালিকায় সরাসরি অপারেশন করতে পারেনassertIterableEquals
থেটাসিনার

assertIterableEqualsjUnit5 @ThetaSinner
iec2011007

উত্তর:


168

আমি বুঝতে পারি যে এটি কয়েক বছর আগে জিজ্ঞাসা করা হয়েছিল, সম্ভবত এই বৈশিষ্ট্যটি তখন ছিল না। তবে এখন কেবল এটি করা সহজ:

@Test
public void test_array_pass()
{
  List<String> actual = Arrays.asList("fee", "fi", "foe");
  List<String> expected = Arrays.asList("fee", "fi", "foe");

  assertThat(actual, is(expected));
  assertThat(actual, is(not(expected)));
}

আপনার যদি জুনিটের সাম্প্রতিক সংস্করণ হ্যামক্রাস্টের সাথে ইনস্টল করা থাকে তবে কেবল এই আমদানিগুলি যুক্ত করুন:

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

http

http://junit.org/junit4/javadoc/latest/org/hamcrest/CoreMatchers.html

http://junit.org/junit4/javadoc/latest/org/hamcrest/core/Is.html


3
System.out.println(actual == expected);মিথ্যা ফিরে আসবে, কিন্তু System.out.println(actual.equals(expected));সত্য ফিরে আসবে।
ক্যাটফিশ

@ ক্যাটফিশ হ্যাঁ, এটি বিভ্রান্তিকর নয় আমি মনে করি যে আমি প্রদর্শন করছি যে ম্যাচচারটি এর .equals(..)পরিবর্তে ব্যবহার করছেন ==?
djeikyb

2
এ্যাসেটক্যালের চেয়ে এটি কীভাবে ভাল?
রায়েডওয়াল্ড

1
যখন দৃ f়তা ব্যর্থ হয় তখন রেডওয়াল্ড আউটপুট দেয়। আমি পার্থক্যটি সম্পাদনা করতে পরে ফিরে আসার চেষ্টা করব। হ্যামক্রাস্ট ম্যাচারগুলি বিশদ ব্যর্থতার বার্তা উত্পন্ন করতে পারে। জুনিটের পক্ষে একই ধার্মিকতার সাথে কেবলমাত্র চাপের পরিমাণগুলি ওভারলোড করা সম্ভব। তবে বেশিরভাগ জুনিট মূল ইউনিট পরীক্ষার বৈশিষ্ট্যগুলি সরবরাহ করে এবং হ্যামক্রেষ্ট একটি সুন্দর-থেকে-অবজেক্ট অবজেক্ট ডিফারেন্স ডেসক্রাইবার লাইব্রেরি সরবরাহ করে।
djeikyb

29

স্ট্রিং এবং তুলনা রূপান্তর করবেন না। এটি পারফিউমেন্সের জন্য ভাল নয়। জুনিটে, কোরেমাটচার্সের অভ্যন্তরে, এই => এর জন্য ম্যাচার রয়েছেhasItems

List<Integer> yourList = Arrays.asList(1,2,3,4)    
assertThat(yourList, CoreMatchers.hasItems(1,2,3,4,5));

এটি একটি ভাল উপায় যা আমি জানি যে তালিকার উপাদানগুলি চেক করা।


2
একটি নোট সহ, নির্বাচিত উত্তর হওয়া উচিত: আপনার যা যা চান তা তালিকায় তালিকায় আর কোনও আইটেম নেই তা যাচাই করার জন্য আপনাকেও যাচাই করতে হবে। হতে পারে ব্যবহার:Assert.assertEquals(4,yourList.size());
yoni

বা একক লাইনের সাথে:assertThat(yourList.toArray(), arrayContainingInAnyOrder(1,2,3,4,5));
ব্যবহারকারী 1778602

3
"এটি পারফিউমেন্সের পক্ষে ভাল নয়" " Unit ইউনিট পরীক্ষা লেখার সময় কার ডিগ্রিটি কারও বিবেচনায় নেওয়া উচিত তা সম্পর্কে আমি নিশ্চিত নই ... তবে নিশ্চিত যে, তাদের toString()সংস্করণের মাধ্যমে স্ট্রিংগুলির তুলনা করা সবচেয়ে ভাল উপায় নয়।
ওয়ালেন

21

এটি উত্তরাধিকারের উত্তর, যা ইউনাইট ৪.৩ এবং এর নীচে উপযুক্ত। JUnit এর আধুনিক সংস্করণে assertThat পদ্ধতিতে অন্তর্নির্মিত পঠনযোগ্য ব্যর্থতা বার্তা অন্তর্ভুক্ত রয়েছে। সম্ভব হলে এই প্রশ্নের অন্যান্য উত্তরগুলি পছন্দ করুন।

List<E> a = resultFromTest();
List<E> expected = Arrays.asList(new E(), new E(), ...);
assertTrue("Expected 'a' and 'expected' to be equal."+
            "\n  'a'        = "+a+
            "\n  'expected' = "+expected, 
            expected.equals(a));

রেকর্ডের জন্য, @ পল যেমন এই উত্তরে তার মন্তব্যে উল্লেখ করেছেন, দু'টি Listসমান:

যদি এবং কেবলমাত্র যদি নির্দিষ্ট বস্তুটিও একটি তালিকা হয় তবে উভয় তালিকার সমান আকার থাকে এবং দুটি তালিকার সমস্ত সংযুক্ত উপাদান সমান হয়। (দুটি উপাদান e1এবং e2সমান যদি (e1==null ? e2==null : e1.equals(e2))।) অন্য কথায়, দুটি তালিকাগুলি সমান হিসাবে সংজ্ঞায়িত করা হয় যদি সেগুলি একই ক্রমে একই উপাদান থাকে। এই সংজ্ঞাটি নিশ্চিত করে যে সমান পদ্ধতিটি Listইন্টারফেসের বিভিন্ন বাস্তবায়ন জুড়ে সঠিকভাবে কাজ করে ।

ইন্টারফেসের জাভডোকগুলিList দেখুন ।


1
সুতরাং আপনার অর্থ প্রত্যাশিত eসামগ্রী (ক) তালিকাটি ধারণ করে থাকা অবজেক্টগুলিকে বোঝানোর জন্য যত্ন নেবে?
কামাল

1
তালিকা জাভাদোক থেকে: সামঞ্জস্যের জন্য এই তালিকাটির সাথে নির্দিষ্ট বস্তুর তুলনা করে। যদি নির্দিষ্ট অবজেক্টটিও একটি তালিকা হয় তবে কেবল এবং সত্যটি প্রত্যাবর্তন হয়, উভয় তালিকার একই আকার থাকে এবং দুটি তালিকার সমস্ত সংযুক্ত উপাদান সমান হয়। (দুটি উপাদান ই 1 এবং ই 2 সমান হয় যদি (e1 == নাল? E2 == নাল: e1.equals (e2))। অন্য কথায়, দুটি তালিকাকে সমান হিসাবে সংজ্ঞায়িত করা হয় যদি তারা একই ক্রমে একই উপাদান থাকে তবে । এই সংজ্ঞাটি নিশ্চিত করে যে সমান পদ্ধতিটি তালিকা ইন্টারফেসের বিভিন্ন বাস্তবায়নে সঠিকভাবে কাজ করে।
পল ম্যাকেনজি

1
এই হতাশ সহায়ক ত্রুটি বার্তা কম প্রদান করে। আমি একটি ইউটিলিটি ক্লাস লিখতে ভাল বলে মনে করেছি যা একটি লুপ সঞ্চালন করে যাতে আপনি দেখতে পারেন কোন উপাদানগুলি আলাদা।
মাইকেল লয়েড লি

@ এম কে, সম্ভবত, তবে আমি এই জাতীয় জিনিসের জন্য একটি কাস্টম ইউটিলিটি পদ্ধতি লিখতে দ্বিধা বোধ করছি। আমি এখনই সম্পাদিত ত্রুটি বার্তা সম্পর্কে কী হবে?
বার্ট কায়ার্স

@ এম কে কে আমি সম্মত হলাম যে প্রতিটি উপাদান পরীক্ষা করার জন্য একটি লুপ লিখতে আরও ভাল হতে পারে তাই আপনি কী জানেন যে আলাদা। এটি তালিকায় কী ধরণের অবজেক্ট রয়েছে তা নির্ভর করে। যদি সেগুলি স্ট্রিং হয় তবে কেবল "a =" + a বলুন ঠিক আছে, তবে যদি তারা জটিল বস্তু হয় (অন্যান্য তালিকাগুলি, বা এমন কিছু যা ভাল স্ট্রিং বাস্তবায়ন না করে) তবে পৃথকভাবে তাদের পরীক্ষা করা আরও সহজ হতে পারে
ম্যাট এন

20

assertEquals(Object, Object)JUnit4 থেকে / JUnit 5 বা assertThat(actual, is(expected));Hamcrest থেকে অন্য উত্তর প্রস্তাবিত শুধুমাত্র উভয় হিসাবে কাজ করবে equals()এবং toString()তুলনা বস্তুর শ্রেণীর (এবং গভীরভাবে) জন্য overrided করছে।

এটি গুরুত্বপূর্ণ কারণ দাবিতে সমতা পরীক্ষা নির্ভর করে equals()এবং পরীক্ষার ব্যর্থতার বার্তা toString()তুলনা করা অবজেক্টগুলির উপর নির্ভর করে ।
জন্য বিল্ট ইন যেমন শ্রেণীর String, Integerএবং তাই জন্য ... এই ওভাররাইড যেমন কোন সমস্যা উভয় equals()এবং toString()। সুতরাং এটি দৃsert়ভাবে দাবি করা List<String>বা List<Integer>সহকারে বৈধ assertEquals(Object,Object)
এবং এই বিষয়টি সম্পর্কে: আপনাকে equals()ক্লাসে ওভাররাইড করতে হবে কারণ এটি অবজেক্টের সমতার ক্ষেত্রে অর্থবোধ করে, কেবল ইউইনিতের সাথে পরীক্ষায় দৃ .়তা আরো সহজ করে তোলে না।
দৃser়তা আরও সহজ করার জন্য আপনার অন্যান্য উপায় রয়েছে।
একটি ভাল অনুশীলন হিসাবে আমি দৃ /়তা / ম্যাচারের লাইব্রেরি পছন্দ করি।

এখানে একটি AssertJ সমাধান রয়েছে।

org.assertj.core.api.ListAssert.containsExactly() আপনার যা প্রয়োজন তা: এটি জাভাডক-এ বর্ণিত অনুসারে প্রকৃত গোষ্ঠীতে প্রদত্ত মানগুলি এবং ঠিক তেমন কিছুই নেই যাচাই করে।

মনে করুন যে কোনও Fooশ্রেণি যেখানে আপনি উপাদান যুক্ত করেন এবং কোথায় আপনি এটি পেতে পারেন।
এর একটি ইউনিট পরীক্ষাFooএটির করে দাবি করে যে দুটি তালিকার একই বিষয়বস্তুর মতো দেখতে পাওয়া যায়:

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

@Test
void add() throws Exception { 
   Foo foo = new Foo();
   foo.add("One", "Two", "Three");
   Assertions.assertThat(foo.getElements())
             .containsExactly("One", "Two", "Three");
}

একটি AssertJ ভাল পয়েন্ট হ'ল যে ঘোষণা List প্রত্যাশিত হিসাবে করা অযথা: এটি আরও পাঠযোগ্য করে তোলে:

Assertions.assertThat(foo.getElements())
         .containsExactly("One", "Two", "Three");

তবে দৃ /়তা / ম্যাচার লাইব্রেরিগুলি আবশ্যক কারণ এগুলি সত্যই আরও এগিয়ে যাবে।
মনে করুন এখন এটি s এর উদাহরণস্বরূপ Foo স্টোর করে না । এটি খুব সাধারণ প্রয়োজন। AssertJ এর সাথে দৃ as়তা লিখতে এখনও সহজ। আরও ভাল আপনি জোর দিয়ে বলতে পারেন যে তালিকার বিষয়বস্তু সমান হয় এমনকি JUnit উপায়ে যখন প্রয়োজন হয় এমন উপাদানগুলির শ্রেণিটি ওভাররাইড না করে:StringBar
equals()/hashCode()

import org.assertj.core.api.Assertions;
import static org.assertj.core.groups.Tuple.tuple;
import org.junit.jupiter.api.Test;

@Test
void add() throws Exception {
    Foo foo = new Foo();
    foo.add(new Bar(1, "One"), new Bar(2, "Two"), new Bar(3, "Three"));
    Assertions.assertThat(foo.getElements())
              .extracting(Bar::getId, Bar::getName)
              .containsExactly(tuple(1, "One"),
                               tuple(2, "Two"),
                               tuple(3, "Three"));
}

7

আপনি যদি উপাদানগুলির ক্রম সম্পর্কে চিন্তা না করেন তবে আমি ListAssert.assertEqualsজুনিট-অ্যাডোনগুলিতে প্রস্তাব দিই।

লিঙ্ক: http://junit-addons.sourceforge.net/

অলস মাভেন ব্যবহারকারীদের জন্য:

    <dependency>
        <groupId>junit-addons</groupId>
        <artifactId>junit-addons</artifactId>
        <version>1.4</version>
        <scope>test</scope>
    </dependency>

7
দ্রষ্টব্য: আপনি যদি উপাদানগুলির ক্রমটির বিষয়ে চিন্তা করেন না তবে আপনার একটি সেট বা সংগ্রহ ব্যবহার করা উচিত, তালিকা নয়।
বেরেট

11
আমি রাজী. এই গ্রন্থাগারটি স্থূল। কেন পৃথিবীতে লিস্টএসার্ট.সার্টএকুয়ালস () ডিফল্টভাবে অর্ডারলেস হবে?
রায়ান

5

আপনি জুনেটে assertEquals ব্যবহার করতে পারেন ।

import org.junit.Assert;   
import org.junit.Test;

    @Test
    public void test_array_pass()
    {
        List<String> actual = Arrays.asList("fee", "fi", "foe");
        List<String> expected = Arrays.asList("fee", "fi", "foe");
        Assert.assertEquals(actual,expected);
    }

যদি উপাদানগুলির ক্রম পৃথক হয় তবে এটি ত্রুটি ফিরে আসবে।

আপনি যদি কোনও মডেল অবজেক্টের তালিকা জোর দিয়ে থাকেন তবে আপনার নির্দিষ্ট মডেলের সমান পদ্ধতিটি ওভাররাইড করা উচিত।

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj != null && obj instanceof ModelName) {
            ModelName other = (ModelName) obj;
            return this.getItem().equals(other.getItem()) ;
        }
        return false;
    }

4

আপনি যদি অ্যারে তালিকা তৈরি করতে না চান তবে আপনি এটি ব্যবহার করে দেখতে পারেন

@Test
public void test_array_pass()
{
  List<String> list = Arrays.asList("fee", "fi", "foe");
  Strint listToString = list.toString();
  Assert.assertTrue(listToString.contains("[fee, fi, foe]"));   // passes  
}


1

চাকা পুনর্নবীকরণ করবেন না!

একটি গুগল কোড লাইব্রেরি রয়েছে যা এটি আপনার জন্য করে: হ্যামক্রেস্ট

[হামক্রস্ট] ম্যাচারের নিয়মগুলি অন্যান্য ফ্রেমওয়ার্কগুলিতে ব্যবহারের জন্য ঘোষণামূলকভাবে সংজ্ঞায়িত করার অনুমতি দেয় ম্যাচার অবজেক্টগুলির (যা সীমাবদ্ধতা বা ভবিষ্যদ্বাণী হিসাবেও পরিচিত) একটি লাইব্রেরি সরবরাহ করে। সাধারণ পরিস্থিতিতে টেস্টিং ফ্রেমওয়ার্ক, উপহাস লাইব্রেরি এবং ইউআই বৈধকরণ নিয়ম অন্তর্ভুক্ত।


0

আমি জানি যে এই সমস্যাটি সমাধান করার জন্য ইতিমধ্যে অনেকগুলি বিকল্প রয়েছে, তবে আমি কোনও পরিবর্তে দুটি তালিকা জোর দেওয়ার জন্য নিম্নলিখিতটিগুলি করতে চাই :

assertTrue(result.containsAll(expected) && expected.containsAll(result))

অর্ডার মেলেনি কি এই ব্যর্থ হবে না ??
iec2011007

0

assertEquals(expected, result);আমার জন্য কাজ কর. যেহেতু এই ফাংশনটি দুটি বস্তু পায় তাই আপনি এতে কোনও কিছু দিতে পারেন।

public static void assertEquals(Object expected, Object actual) {
    AssertEquals.assertEquals(expected, actual);
}

-1

উপরের সমস্ত উত্তরগুলি আমি বস্তুর দুটি তালিকার তুলনা করার জন্য সঠিক সমাধান দিচ্ছি না। উপরোক্ত পদ্ধতির বেশিরভাগগুলি কেবল তুলনার সীমাবদ্ধতার ক্ষেত্রেই সহায়ক হতে পারে - আকারের তুলনা - রেফারেন্স তুলনা

তবে যদি আমাদের কাছে বস্তুর স্তরের বিভিন্ন আকারের অবজেক্টের তালিকা এবং বিভিন্ন ডেটা থাকে তবে এই তুলনা পদ্ধতির সাহায্য করবে না।

আমি মনে করি নীচের পদ্ধতিটি ব্যবহারকারী-সংজ্ঞায়িত অবজেক্টে ওভাররাইডিং সমান এবং হ্যাশকোড পদ্ধতিতে পুরোপুরি কাজ করবে।

আমি এক্সস্ট্রিম ব্যবহার করেছি ওভাররাইড সমান এবং হ্যাশকোডের জন্য লিবিব ব্যবহার করেছি তবে আমরা জিতে থাকা লজিক / তুলনাটিও সমান ও হ্যাশকোডকে ওভাররাইড করতে পারি।

আপনার রেফারেন্সের জন্য উদাহরণ এখানে

    import com.thoughtworks.xstream.XStream;

    import java.text.ParseException;
    import java.util.ArrayList;
    import java.util.List;

    class TestClass {
      private String name;
      private String id;

      public void setName(String value) {
        this.name = value;
      }

      public String getName() {
        return this.name;
      }

      public String getId() {
        return id;
      }

      public void setId(String id) {
        this.id = id;
      }

      /**
       * @see java.lang.Object#equals(java.lang.Object)
       */
      @Override
      public boolean equals(Object o) {
        XStream xstream = new XStream();
        String oxml = xstream.toXML(o);
        String myxml = xstream.toXML(this);

        return myxml.equals(oxml);
      }

      /**
       * @see java.lang.Object#hashCode()
       */
      @Override
      public int hashCode() {
        XStream xstream = new XStream();
        String myxml = xstream.toXML(this);
        return myxml.hashCode();
      }
    }

    public class XstreamCompareTest {
      public static void main(String[] args) throws ParseException {
      checkObjectEquals();
}

      private static void checkObjectEquals() {
        List<TestClass> testList1 = new ArrayList<TestClass>();
        TestClass tObj1 = new TestClass();
        tObj1.setId("test3");
        tObj1.setName("testname3");
        testList1.add(tObj1);

        TestClass tObj2 = new TestClass();
        tObj2.setId("test2");
        tObj2.setName("testname2");
        testList1.add(tObj2);

        testList1.sort((TestClass t1, TestClass t2) -> t1.getId().compareTo(t2.getId()));

        List<TestClass> testList2 = new ArrayList<TestClass>();
        TestClass tObj3 = new TestClass();
        tObj3.setId("test3");
        tObj3.setName("testname3");
        testList2.add(tObj3);

        TestClass tObj4 = new TestClass();
        tObj4.setId("test2");
        tObj4.setName("testname2");
        testList2.add(tObj4);

        testList2.sort((TestClass t1, TestClass t2) -> t1.getId().compareTo(t2.getId()));

        if (isNotMatch(testList1, testList2)) {
          System.out.println("The list are not matched");
        } else {
          System.out.println("The list are matched");
        }

      }

      private static boolean isNotMatch(List<TestClass> clist1, List<TestClass> clist2) {
        return clist1.size() != clist2.size() || !clist1.equals(clist2);
      }
    }

সর্বাধিক গুরুত্বপূর্ণ বিষয় হ'ল আপনি যদি অবজেক্টের সমান চেকের কোনও ক্ষেত্রকে অন্তর্ভুক্ত করতে না চান তবে আপনি টীকাগুলি (@ এক্সস্ট্রিমঅমিফিল্ড) দ্বারা ক্ষেত্রগুলি উপেক্ষা করতে পারেন। কনফিগার করার জন্য এর মতো অনেক টিক চিহ্ন রয়েছে তাই এই লিবের টীকাগুলি সম্পর্কে গভীর দৃষ্টি দেওয়া উচিত।

আমি নিশ্চিত যে এই উত্তরটি আপনার দুটি বস্তুর তালিকার তুলনার জন্য সঠিক পদ্ধতির সনাক্তকরণের জন্য সময় সাশ্রয় করবে :)। আপনি যদি এই বিষয়ে কোন সমস্যা দেখতে পান তবে মন্তব্য করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.