मैं ओपी के दृष्टिकोण से पूरी तरह सहमत हूं। Assert.assertFalse(expected.equals(actual))
एक असमानता को व्यक्त करने का स्वाभाविक तरीका नहीं है।
लेकिन मैं तर्क दूंगा कि आगे से Assert.assertEquals()
, Assert.assertNotEquals()
काम करता है , लेकिन दस्तावेज़ के लिए उपयोगकर्ता के अनुकूल नहीं है कि परीक्षा वास्तव में क्या कहती है और यह समझने / बहस करने में विफल हो जाती है कि क्या है।
तो हाँ JUnit 4.11 और JUnit 5 प्रदान करता है Assert.assertNotEquals()
( Assertions.assertNotEquals()
JUnit 5 में), लेकिन मैं वास्तव में उनका उपयोग करने से बचता हूँ।
विकल्प के रूप में, किसी वस्तु की स्थिति का पता लगाने के लिए, मैं सामान्य रूप से एक माचिस की एपीआई का उपयोग करता हूं जो कि वस्तु स्थिति में आसानी से खोद लेती है, यह दस्तावेज स्पष्ट रूप से अभिकथन का उद्देश्य है और यह बहुत ही उपयोगकर्ता के अनुकूल है कि दावे की विफलता का कारण समझें।
यहाँ एक उदाहरण है।
मान लीजिए कि मेरे पास एक एनिमल क्लास है, जिसे मैं 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);
}
}
JUnit 4.11+ (या JUnit 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.AssertionError: मान भिन्न होना चाहिए। वास्तविक: पशु
[नाम = स्कौबी, आयु = १०, पसंदीदा = घास]
org.junit.Assert.fail (Assert.java:88) पर
ठीक है वस्तुओं के बराबर नहीं हैं। लेकिन समस्या कहां है?
परीक्षण विधि में किस क्षेत्र का सही मान नहीं है? एक ? दो ? उन सभी को ?
इसे खोजने के लिए आपको createWithNewNameAndAge()
कार्यान्वयन में खुदाई करनी होगी / डिबगर का उपयोग करना होगा, जबकि परीक्षण एपीआई बहुत अधिक अनुकूल होगा यदि यह हमारे लिए वह अंतर बनाएगा जिसकी अपेक्षा की जाती है और जो प्राप्त होता है।
परीक्षण धावक के रूप में JUnit 4.11 और जोर उपकरण के रूप में एक परीक्षण मिलान एपीआई
यहाँ परीक्षण का एक ही परिदृश्य है, लेकिन जो Animal
राज्य के दावे को बनाने के लिए AssertJ (एक उत्कृष्ट परीक्षण माचिस API) का उपयोग करता है :
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]>
junit5.MyTest.assertListNotEquals_AssertJ (MyTest.jpg:26) पर
हम पढ़ सकते हैं कि Animal::getName, Animal::getAge, Animal::getFavoriteFood
लौटे हुए जानवरों के मूल्यों के लिए, हम इन मानों की अपेक्षा करते हैं:
"little scoubi", 1, "hay"
लेकिन हमारे पास ये मूल्य हैं:
"scoubi", 10, "hay"
इसलिए हम जानते हैं कि कहां जांच की जाती है: name
और age
सही ढंग से मूल्यवान नहीं हैं। इसके अतिरिक्त, रिटर्न के अधिक सूक्ष्मता के लिए भी अनुमति hay
के दावे में मूल्य निर्दिष्ट करने का तथ्य । हम चाहते हैं कि वस्तुएं कुछ गुणों के लिए समान न हों लेकिन जरूरी नहीं कि वे हर गुणों के लिए हों।
तो निश्चित रूप से, माचिस एपीआई का उपयोग करना अधिक स्पष्ट और लचीला है।Animal::getFavoriteFood()
Animal