আমি ওপি পয়েন্টের সাথে একমত 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
। আমরা চাই যে কিছু বৈশিষ্ট্যের জন্য অবজেক্টগুলি একরকম না হয় তবে প্রতিটি বৈশিষ্ট্যের জন্য অগত্যা।
সুতরাং স্পষ্টতই, ম্যাচার এপিআই ব্যবহার করা অনেক বেশি পরিষ্কার এবং নমনীয়।