JUnit কেন assertNotEquals পদ্ধতি সরবরাহ করে না?


429

কেউ কি জানে কেন 4 ইউনাইট 4 পদ্ধতি সরবরাহ করে assertEquals(foo,bar)না assertNotEqual(foo,bar)?

এটি সরবরাহ করে assertNotSame(অনুরূপ assertSame) এবং assertFalse(এর সাথে সম্পর্কিত assertTrue), সুতরাং এটি আশ্চর্যজনক বলে মনে হচ্ছে যে তারা এতে অন্তর্ভুক্ত করেনি assertNotEqual

যাইহোক, আমি জানি যে JUnit-addons যে পদ্ধতিগুলি আমি সন্ধান করছি তা সরবরাহ করে। আমি শুধু কৌতুহল জিজ্ঞাসা করছি।


কমপক্ষে JUnit 4.12 থেকে, assertNotEquals সরবরাহ করা হয়েছে। জুনিট.আর.জুনিট ৪
জাভাদোক /

উত্তর:


403

আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি আরও নতুন assertThat()স্টাইলের দৃ use়তা ব্যবহার করুন , যা সহজেই সমস্ত ধরণের উপকারিতা বর্ণনা করতে পারে এবং স্বয়ংক্রিয়ভাবে আপনি কী প্রত্যাশা করেছিলেন এবং জবাবটি ব্যর্থ হলে আপনি কী পেয়েছিলেন তা বিবরণ তৈরি করতে পারে:

assertThat(objectUnderTest, is(not(someOtherObject)));
assertThat(objectUnderTest, not(someOtherObject));
assertThat(objectUnderTest, not(equalTo(someOtherObject)));

তিনটি বিকল্প সমতুল্য, আপনি সবচেয়ে পঠনযোগ্য বলে বেছে নিন।

পদ্ধতির সাধারণ নামগুলি ব্যবহার করতে (এবং এই উত্তেজনাপূর্ণ সিনট্যাক্সটিকে কাজ করার অনুমতি দিন), আপনার এই আমদানিগুলি দরকার:

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

134
আমি বিকল্প কথন বাক্য গঠন করতে পয়েন্টার প্রশংসা করি, কিন্তু অন্যত্র ইশারা উত্তর না কেন JUnit কখনো দেওয়া assertNotEquals()
সেহ

14
@ সেঃ আমি যেভাবে প্রশ্নটি পড়েছি তা historicalতিহাসিক আগ্রহের বিষয়ে নয়, তবে জুনিত পরীক্ষায় "এই দুটি বিষয় সমান নয়" বলে দাবিটি গঠনের একটি উপায়। আমি উত্তর দিয়েছি। "কেন সেখানে / ছিল না" বিবেচনা করে assertNotEqualআমি বলব কারণ এটি একটি বিশেষায়িত দাবি যা প্রায়শই প্রয়োজন হয় না assertEqualsএবং তাই জেনেরিকের মাধ্যমে প্রকাশ করা হবে assertFalse
জোছিম সউর

21
"আপনি সবচেয়ে পঠনযোগ্য হিসাবে বেছে নিন"। ইউনিট পরীক্ষা পড়া এবং লেখার লোকেরা প্রোগ্রামার are তারা কি সত্যিই assertNotEqual (অবজেক্টউন্ডারস্টেস্ট, কিছু অন্যরকম) বা assertFalse (অবজেক্টউন্ডারটেষ্ট.কুইকালস (সামান্যআউটজেক্ট)) এর চেয়ে বেশি পঠনযোগ্য খুঁজে পেয়েছেন? আমি অভিনব ম্যাচার এপিআই দ্বারা বিশ্বাসী নই - কোনও প্রোগ্রামার তাদের কীভাবে ব্যবহার করবেন তা অন্বেষণ / আবিষ্কার করা যথেষ্ট শক্ত বলে মনে হচ্ছে ...
বাচার

@ ব্যাকার: কিছু জোরের জন্য এটি মূলত স্টাইলের বিষয়। তবে উপলব্ধ পদ্ধতিগুলির assertThatসীমিত সেটের চেয়ে সম্পূর্ণ অনেক বেশি অভিব্যক্তিপূর্ণ assert*। অতএব আপনি একক লাইনে সঠিক সীমাবদ্ধতা প্রকাশ করতে পারেন, এটি (প্রায়) একটি ইংরেজী বাক্যের মতো পড়ুন এবং দৃsert়তা ব্যর্থ হলে অর্থবোধক বার্তা পান। মঞ্জুর, এটি সর্বদা একটি হত্যাকারী বৈশিষ্ট্য নয়, আপনি যখন এটি কয়েকবার কার্যকরভাবে দেখেছেন, আপনি দেখবেন এটি কতটা মূল্য যুক্ত করে।
জোছিম সউর

5
@ জোয়াচিম আমি সম্মত হলাম যে এটির assertThatচেয়েও বেশি অভিব্যক্তিপূর্ণ assert*, তবে assert*আপনি সাধারণভাবে প্রকাশের ভিতরে এবং বাইরে প্রকাশ করতে পারেন এমন জাভা প্রকাশের চেয়ে এটি বেশি উদ্বেগজনক বলে মনে করি না (সর্বোপরি আমি জাভা কোডে কোনও কিছু প্রকাশ করতে পারি)। এটি একটি সাধারণ সমস্যা যা আমি সাবলীল শৈলীর এপিআই দিয়ে শুরু করতে শুরু করি - প্রত্যেকটিই মূলত আপনাকে শিখতে হবে একটি নতুন ডিএসএল (যখন আমরা সবাই ইতিমধ্যে জাভাটিকে জানি!)। আমি মনে করি যে হ্যামক্রাস্ট এখন সর্বব্যাপী, যদিও এটি লোকেরা জানতে পারে তা আশা করা যুক্তিসঙ্গত। আমার একটি নাটক হবে ...

154

assertNotEqualsJUnit 4.11 এ একটি রয়েছে: https://github.com/ junit-team/ junit/blob/master/doc/ReleaseNotes4.11.md# सुधार

import static org.junit.Assert.assertNotEquals;

1
মাইন্ড, জেমক (২.6.০) মভেন আর্টফ্যাক্টগুলির মধ্যে একটি জুনিট-ডিপ এর একটি পুরানো সংস্করণ ফাঁস করে যার ফলস্বরূপ অ্যাসেটনোটকুয়ালগুলি ছাড়াই একটি অ্যাসেট-ক্লাস রয়েছে। আইভি ব্যবহার করার সময় এটি বাদ দেওয়া ভাল।
gkephorus

7
আমি 4.12 ব্যবহার করছি তবে এখনও assertNotEqual সন্ধান করতে সক্ষম হই না। : s
মুবাশার

49

আমিও অবাক হই। এ্যাসেটের এপিআই খুব সিম্যাট্রিক নয়; পরীক্ষার জন্য কিনা বস্তু, একই এটি উপলব্ধ করা assertSameএবং assertNotSame

অবশ্যই, এটি লেখার খুব বেশি সময় নয়:

assertFalse(foo.equals(bar));

এইরকম দৃser়তা হিসাবে, আউটপুটটির একমাত্র তথ্যমূলক অংশটি দুর্ভাগ্যক্রমে পরীক্ষা পদ্ধতির নাম, সুতরাং বর্ণনামূলক বার্তাটি আলাদাভাবে গঠন করা উচিত:

String msg = "Expected <" + foo + "> to be unequal to <" + bar +">";
assertFalse(msg, foo.equals(bar));

এটি অবশ্যই এত ক্লান্তিকর, এটি নিজের নিজের রোল করা ভাল assertNotEqual। ভাগ্যক্রমে ভবিষ্যতে এটি JUnit: JUnit ইস্যু 22 এর অংশ হতে পারে


19
তবে এটি কম দরকারী, কারণ JUnit আপনাকে একটি সহায়ক ব্যর্থতা বার্তা উত্পন্ন করতে পারে না, উদাহরণস্বরূপ, foo এবং বারের অসম মান। আসল ব্যর্থতার কারণটি লুকানো এবং একটি সাধারণ বুলিয়ানে পরিণত হয়েছে।
বেন জেমস

3
আমি সম্পূর্ণভাবে রাজী. বিশেষত assertFalse আউটপুট উত্পাদন করার জন্য সঠিক বার্তা যুক্তি প্রয়োজন যা আসলে ভুল হয়েছে went
মিক্কো মৌনু

আমি মনে করি এটি পাঠ্য উপস্থিত পরীক্ষাগুলির জন্য কার্যকর। Thnx
মারোউনে গাজানাই

পাঠ্যের ক্ষেত্রে সমস্যাটি হ'ল কোডটি বিকশিত হওয়ার সাথে সাথে এটি পুরানো হয়ে যাবে।
মার্ক লেভিসন

13

আমি যুক্তি দিয়েছি যে assertNotEqual এর অনুপস্থিতি প্রকৃতপক্ষে একটি অসম্পূর্ণতা এবং JUnit কে কিছুটা কম শেখার যোগ্য করে তোলে। মনে রাখবেন যে এটি একটি ঝরঝরে কেস যখন কোনও পদ্ধতি যুক্ত করা হয় তখন API এর জটিলতা হ্রাস পাবে, কমপক্ষে আমার জন্য: প্রতিসাম্য বড় স্থানটিকে শাসন করতে সহায়তা করে। আমার ধারণা হ'ল বাদ দেওয়ার কারণ হতে পারে যে পদ্ধতিটির জন্য খুব কম লোক ডাকছেন। তবুও, আমি এমন একটি সময় মনে করি যখন এমনকি দাবী ফালসের অস্তিত্ব ছিল না; অতএব, আমার একটি ইতিবাচক প্রত্যাশা রয়েছে যে পদ্ধতিটি শেষ পর্যন্ত যুক্ত হতে পারে, যদিও এটি কোনও কঠিন নয়; যদিও আমি স্বীকার করি যে এখানে প্রচুর পরিমাণে কাজের, এমনকি মার্জিতও রয়েছে।


7

আমি এই পার্টিতে বেশ দেরিতে আসছি তবে আমি ফর্মটি পেয়েছি:

static void assertTrue(java.lang.String message, boolean condition) 

বেশিরভাগ 'সমান নয়' ক্ষেত্রে কাজ করার জন্য তৈরি করা যেতে পারে।

int status = doSomething() ; // expected to return 123
assertTrue("doSomething() returned unexpected status", status != 123 ) ;

4
এটি যখন কাজ করে তবে সমস্যাটি হ'ল যদি দৃ f়তা ব্যর্থ হয় তবে এটি কেবল "এক্সপেক্টড ট্রু, কিন্তু মিথ্যা ছিল" বা অন্য কোনও অস্পষ্ট বিবৃতি বলে। কী দুর্দান্ত হবে তা যদি প্রত্যাশিত হয় 123 নয়, তবে 123.
স্টিলথ রাব্বি

6

আমি JUnit4.12 ব্যবহার করে জাভা 8 পরিবেশে JUnit এ কাজ করছি

আমার জন্য: সংকলক আমি ব্যবহার করার পরেও পদ্ধতিটি assertNotEquals সন্ধান করতে সক্ষম হইনি
import org.junit.Assert;

তাই আমি পরিবর্তিত
assertNotEquals("addb", string);
করতে
Assert.assertNotEquals("addb", string);

সুতরাং যদি আপনি assertNotEqualস্বীকৃত না হওয়া সম্পর্কিত সমস্যার মুখোমুখি হন , তবে এটিতে এটি পরিবর্তন করুন Assert.assertNotEquals(,);আপনার সমস্যার সমাধান করা উচিত


1
এর কারণ পদ্ধতিগুলি অচল এবং আপনার অবশ্যই এটি স্ট্যাটিকালি আমদানি করতে পারেন। এটি ব্যবহার করুন import static org.junit.Assert.*;এবং আপনি শ্রেণীর নাম ছাড়াই সমস্ত সংস্থান ব্যবহার করতে সক্ষম হবেন।
টম স্টোন

3

লোকেরা নোটইক্যুয়ালস () নির্ধারণের স্পষ্ট কারণটি হ'ল বিল্টিনগুলি প্রথমে সম্পূর্ণ বিকশিত বস্তুতে রূপান্তর না করে তুলনা করা:

ভার্জোজ উদাহরণ:

....
assertThat(1, not(equalTo(Integer.valueOf(winningBidderId))));
....

বনাম

assertNotEqual(1, winningBidderId);

দুর্ভাগ্যক্রমে যেহেতু Eclipse এ JUnit 4.11 কে ডিফল্টরূপে অন্তর্ভুক্ত করে না আপনি অবশ্যই ভার্বোজ হতে হবে।

ক্যাভেট আমি মনে করি না যে '1' একটি পূর্ণসংখ্যার মধ্যে আবৃত হওয়া দরকার val মূল্যবোধ () তবে যেহেতু আমি নতুন থেকে ফিরে এসেছি my নেট আমার সঠিকতার উপর নির্ভর করে না।


1

পূর্ববর্তী পরীক্ষার প্রতিবেদনে যেমন দাবি করা ব্যর্থতার পক্ষে ভিন্নতা দেখাবে ঠিক তেমনি অ্যাসেটফালসে নেতিবাচক দৃ as়তার জন্য হ্যামক্রেস্ট ব্যবহার করা ভাল।

আপনি যদি assertFalse ব্যবহার করেন তবে আপনি কেবল প্রতিবেদনে একটি দৃ failure় ব্যর্থতা পাবেন। অর্থাত ব্যর্থতার কারণ হারিয়ে তথ্য।


1

সাধারণত যখন আমি দুটি বস্তুর সমান হওয়ার আশা করি তখন আমি এটি করি:

assertTrue(obj1.equals(obj2));

এবং:

assertFalse(obj1.equals(obj2));

যখন তারা অসম হবে বলে আশা করা হচ্ছে। আমি সচেতন যে এটি আপনার প্রশ্নের উত্তর নয় তবে এটি আমি কাছে পেতে পারি। এটি অন্যদের JUnit 4.11 এর আগে JUnit সংস্করণগুলিতে কী করতে পারে তা অনুসন্ধান করতে অন্যদের সহায়তা করতে পারে।


0

আমি ওপি পয়েন্টের সাথে একমত Assert.assertFalse(expected.equals(actual))অসমতা প্রকাশ করার কোনও প্রাকৃতিক উপায় নয়।
কিন্তু আমি চেয়ে যে আরও তর্ক করবে Assert.assertEquals(), Assert.assertNotEquals()কাজ কিন্তু ব্যবহারকারী ডকুমেন্ট কি পরীক্ষা আসলে দাবি এবং বুঝতে / ডিবাগ যেমন কথন ব্যর্থ করার উপযোগী নয়।
সুতরাং হ্যাঁ JUnit 4.11 এবং JUnit 5 সরবরাহ করে Assert.assertNotEquals()( Assertions.assertNotEquals()JUnit 5 এ) তবে আমি সত্যিই সেগুলি এড়াতে চাই না।

বিকল্প হিসাবে, কোনও অবজেক্টের অবস্থা জোর দেওয়ার জন্য আমি সাধারণভাবে ম্যাচার এপিআই ব্যবহার করি যা সহজেই অবজেক্টের রাজ্যে খনন করে, সেই নথিটি স্পষ্টতই দৃser়প্রকাশের উদ্দেশ্য এবং এটি দৃ user় ব্যর্থতার কারণটি বোঝার জন্য খুব ব্যবহারকারী বান্ধব।

এখানে একটি উদাহরণ।
ধরুন আমার কাছে একটি অ্যানিমাল ক্লাস রয়েছে যা আমি createWithNewNameAndAge()পদ্ধতিটি পরীক্ষা করতে চাই , এমন একটি পদ্ধতি যা নাম এবং বয়স পরিবর্তন করে তবে তার পছন্দসই খাবার রেখে নতুন প্রাণীর অবজেক্ট তৈরি করে।
ধরুন আমি Assert.assertNotEquals()জোর দিয়ে বলছি যে আসল এবং নতুন বস্তুগুলি পৃথক।
এখানে ত্রুটিযুক্ত বাস্তবায়ন সহ প্রাণী শ্রেণি এখানে রয়েছে createWithNewNameAndAge():

public class Animal {

    private String name;
    private int age;
    private String favoriteFood;

    public Animal(String name, int age, String favoriteFood) {
        this.name = name;
        this.age = age;
        this.favoriteFood = favoriteFood;
    }

    // Flawed implementation : use this.name and this.age to create the 
    // new Animal instead of using the name and age parameters
    public Animal createWithNewNameAndAge(String name, int age) {
        return new Animal(this.name, this.age, this.favoriteFood);
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getFavoriteFood() {
        return favoriteFood;
    }

    @Override
    public String toString() {
        return "Animal [name=" + name + ", age=" + age + ", favoriteFood=" + favoriteFood + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((favoriteFood == null) ? 0 : favoriteFood.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Animal)) return false;

        Animal other = (Animal) obj;
        return age == other.age && favoriteFood.equals(other.favoriteFood) &&
                name.equals(other.name);
    }

}

পরীক্ষার রানার এবং দৃser় সরঞ্জাম হিসাবে উভয়ই জুনিট 4.11+ (বা জুনিট 5)

@Test
void assertListNotEquals_JUnit_way() {
    Animal scoubi = new Animal("scoubi", 10, "hay");
    Animal littleScoubi = scoubi.createWithNewNameAndAge("little scoubi", 1);
    Assert.assertNotEquals(scoubi, littleScoubi);
}

প্রত্যাশার মতো পরীক্ষাটি ব্যর্থ হয় তবে বিকাশকারীকে সরবরাহ করা কারণটি সত্যই সহায়ক নয়। এটি কেবল বলেছে যে মানগুলি পৃথক হওয়া উচিত এবং ফলাফলটি toString()প্রকৃত Animalপ্যারামিটারে আউটপুট করা উচিত :

java.lang.SsertionError: মানগুলি আলাদা হওয়া উচিত। আসল: প্রাণী

[নাম = স্কৌবি, বয়স = 10, প্রিয়ফুড = খড়]

org.junit.Assert.fail এ (Assert.java:88)

ঠিক আছে বস্তু সমান নয়। তবে সমস্যা কোথায়?
পরীক্ষিত পদ্ধতিতে কোন ক্ষেত্রটি সঠিকভাবে মূল্যবান নয়? এক ? দুটো? তাদের সবাই ?
এটি আবিষ্কার করতে আপনাকে createWithNewNameAndAge() বাস্তবায়নটি খনন করতে হবে / একটি ডিবাগার ব্যবহার করতে হবে যখন টেস্টিং এপিআই যদি আরও আমাদের পক্ষে প্রত্যাশিত এবং কোনটি অর্জিত হয় তার মধ্যে পার্থক্য তৈরি করে friendly


পরীক্ষার রানার হিসাবে জুনিট 4.11 এবং আসক্তি সরঞ্জাম হিসাবে একটি পরীক্ষার ম্যাচার এপিআই

এখানে পরীক্ষার একই পরিস্থিতি কিন্তু এতে AssertJ (একটি দুর্দান্ত পরীক্ষার ম্যাচার এপিআই) ব্যবহার করা হয়েছে রাষ্ট্রের দৃ the় বক্তব্যটি Animal:

import org.assertj.core.api.Assertions;

@Test
void assertListNotEquals_AssertJ() {
    Animal scoubi = new Animal("scoubi", 10, "hay");
    Animal littleScoubi = scoubi.createWithNewNameAndAge("little scoubi", 1);
    Assertions.assertThat(littleScoubi)
              .extracting(Animal::getName, Animal::getAge, Animal::getFavoriteFood)
              .containsExactly("little scoubi", 1, "hay");
}

অবশ্যই পরীক্ষাটি এখনও ব্যর্থ হয় তবে এবার কারণটি পরিষ্কারভাবে বলা হয়েছে:

java.lang.AssertionError:

আশা করা:

<["স্কৌবি", 10, "খড়"]>

ঠিক (এবং একই ক্রমে) ধারণ করতে:

<["ছোট স্কাউবি", 1, "খড়"]>

তবে কিছু উপাদান পাওয়া যায় নি:

<["ছোট স্কাউবি", 1]>

এবং অন্যদের প্রত্যাশিত ছিল না:

<["স্কৌবি", 10]>

জুনিট 5.মাইটিস্ট.আসর্টলিস্ট নট এক্সক্লুসি_সেসার্টজে (মাই টেস্ট.জভা 26)

আমরা পড়তে পারি যে Animal::getName, Animal::getAge, Animal::getFavoriteFoodফিরে আসা প্রাণীর মানগুলির জন্য আমরা এই মানগুলি আশা করি:

"little scoubi", 1, "hay" 

তবে আমাদের এই মানগুলি রয়েছে:

"scoubi", 10, "hay"

সুতরাং আমরা জানি কোথায় তদন্ত হয়: nameএবং ageসঠিকভাবে মূল্যবান হয় না। তদ্ব্যতীত, hayদৃ in ়তার মধ্যে মূল্য নির্দিষ্টকরণের বিষয়টি Animal::getFavoriteFood()প্রত্যাবর্তনকে আরও সূক্ষ্মভাবে দৃsert় করতে দেয় Animal। আমরা চাই যে কিছু বৈশিষ্ট্যের জন্য অবজেক্টগুলি একরকম না হয় তবে প্রতিটি বৈশিষ্ট্যের জন্য অগত্যা।
সুতরাং স্পষ্টতই, ম্যাচার এপিআই ব্যবহার করা অনেক বেশি পরিষ্কার এবং নমনীয়।


-1

Modulo API ধারাবাহিকতা, JUnit কেন সরবরাহ করেনি assertNotEquals()একই কারণ JUnit কখনই এর মতো পদ্ধতি সরবরাহ করে না

  • assertStringMatchesTheRegex(regex, str) বনাম assertStringDoesntMatchTheRegex(regex, str)
  • assertStringBeginsWith(prefix, str) বনাম assertStringDoesntBeginWith(prefix, str)

অর্থাত্ আপনার দৃser় যুক্তিতে আপনি যে ধরণের জিনিসগুলি চাইবেন তার জন্য একটি নির্দিষ্ট দাবি পদ্ধতি সরবরাহ করার কোনও শেষ নেই!

অনেক ভালো মত composable পরীক্ষা প্রিমিটিভের প্রদান equalTo(...), is(...), not(...), regex(...)এবং প্রোগ্রামার টুকরা ঐ একসঙ্গে পরিবর্তে আরো পাঠযোগ্যতা এবং মানসিক সুস্থতা জন্য করা যাক।


3
ভাল, কিছু কারণে, assertEquals () বিদ্যমান। এটি করার দরকার নেই, তবে তা আছে। প্রশ্নটি ছিল প্রতিসামতার ঘাটতি সম্পর্কে - কেন assertEquals উপস্থিত থাকে তবে এর সমকক্ষ নয়?
foo বিন্যাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.