בודקים עם המקרסט

1. סקירה כללית

המקרסט היא המסגרת הידועה המשמשת לבדיקת יחידות במערכת האקולוגית של Java. הוא מקובץ ב- JUnit ובמילים פשוטות, הוא משתמש בפרדיקטים קיימים - הנקראים כיתות התאמה - לצורך קביעת קביעות.

במדריך זה, אנו חקור את ה- API של Hamcrest ולמד כיצד לנצל זאת כדי לכתוב בדיקות יחידה מסודרות ואינטואיטיביות יותר עבור התוכנה שלנו.

2. הגדרת Hamcrest

אנחנו יכולים להשתמש המקרסט עם maven על ידי הוספת התלות הבאה שלנו pom.xml קוֹבֶץ:

 org.hamcrest hamcrest-all 1.3 

הגרסה האחרונה של הספרייה הזו נמצאת תמיד כאן.

3. מבחן לדוגמא

המקרסט משמש בדרך כלל עם צומת ומסגרות בדיקה אחרות לביצוע קביעות. באופן ספציפי, במקום להשתמש צומתרבים לִטעוֹן בשיטות, אנו משתמשים רק בסינגל ה- API טוענים כי הצהרה עם התאמות מתאימות.

בואו נסתכל על דוגמה שבודקת שתיים חוּטs לשוויון ללא קשר למקרה. זה אמור לתת לנו מושג ברור כיצד המקרסט משתלב בשיטת בדיקה:

Class class StringMatcherTest {@Test public void given2Strings_whenEqual_thenCorrect () {String a = "foo"; מחרוזת b = "FOO"; assertThat (a, equalToIgnoringCase (b)); }}

בסעיפים הבאים נבחן כמה התאמות נפוצות אחרות המקרסט הצעות.

4. ה לְהִתְנַגֵד שידוך

המקרסט מספק התאמות לביצוע קביעות על אובייקטים של Java שרירותיים.

לטעון כי ה toString שיטה של לְהִתְנַגֵד מחזיר צוין חוּט:

@ מבחן חלל ציבורי givenBean_whenToStringReturnsRequiredString_thenCorrect () {אדם אדם = אדם חדש ("צריף", "וושינגטון"); מחרוזת str = person.toString (); assertThat (אדם, hasToString (str)); }

אנו יכולים גם לבדוק כי מחלקה אחת היא תת-מחלקה של אחרת:

@Test public void given2Classes_whenOneInheritsFromOther_thenCorrect () {assertThat (Cat.class, typeCompatibleWith (Animal.class)); }}

5. התאמה לשעועית

אנחנו יכולים להשתמש המקרסטהתאמת שעועית לבדיקת מאפיינים של שעועית ג'אווה.

נניח את הדברים הבאים אדם אפונה:

אדם בכיתה ציבורית {שם מחרוזת; כתובת מחרוזת; אדם ציבורי (String personName, String personAddress) {name = personName; כתובת = אדם כתובת; }}

אנחנו יכולים לבדוק אם לשעועית יש את הנכס, שֵׁם ככה:

@ מבחן בטל פומבי givenBean_whenHasValue_thenCorrect () {אדם אדם = אדם חדש ("Baeldung", 25); assertThat (אדם, hasProperty ("שם")); }

אנחנו יכולים גם לבדוק אם אדם יש את כתובת נכס, מאותחל לניו יורק:

@ מבט פומבי בטל שניתן Bean_whenHasCorrectValue_thenCorrect () {אדם אדם = אדם חדש ("Baeldung", "ניו יורק"); assertThat (אדם, hasProperty ("כתובת", שווה ל ("ניו יורק")); }

אנחנו יכולים גם לבדוק אם שניים אדם אובייקטים בנויים עם אותם ערכים:

@ מבחן בטל פומבי given2Beans_whenHavingSameValues_thenCorrect () {Person person1 = אדם חדש ("Baeldung", "New York"); אדם אדם 2 = אדם חדש ("באלדונג", "ניו יורק"); assertThat (person1, samePropertyValuesAs (person2)); } 

6. ה אוסף שידוך

המקרסט מספק התאמות לבדיקה אוסףס.

בדוק פשוט כדי לברר אם א אוסף זה ריק:

@Test הציבור בטל givenCollection_whenEmpty_thenCorrect () {רשימה emptyList = ArrayList חדש (); assertThat (ריק רשימה, ריק ()); }

כדי לבדוק את גודל א אוסף:

@Test public void givenAList_whenChecksSize_thenCorrect () {List hamcrestMatchers = Arrays.asList ("אוספים", "שעועית", "טקסט", "מספר"); assertThat (hamcrestMatchers, hasSize (4)); }

אנו יכולים להשתמש בו גם כדי לקבוע כי למערך יש גודל נדרש:

@ מבחן בטל פומבי givenArray_whenChecksSize_thenCorrect () {String [] hamcrestMatchers = {"אוספים", "שעועית", "טקסט", "מספר"}; assertThat (hamcrestMatchers, arrayWithSize (4)); }

כדי לבדוק אם א אוסף מכיל חברים שניתנו, ללא קשר לסדר:

@Test public void givenAListAndValues_whenChecksListForGivenValues_thenCorrect () {List hamcrestMatchers = Arrays.asList ("אוספים", "שעועית", "טקסט", "מספר"); assertThat (hamcrestMatchers, containInAnyOrder ("שעועית", "טקסט", "אוספים", "מספר")); }

כדי לקבוע עוד כי אוסף לחברים יש סדר:

@Test הציבור בטל givenAListAndValues_whenChecksListForGivenValuesWithOrder_thenCorrect () {רשימה hamcrestMatchers = Arrays.asList ("אוספים", "שעועית", "טקסט", "מספר"); assertThat (hamcrestMatchers, מכיל ("אוספים", "שעועית", "טקסט", "מספר")); }

כדי לבדוק אם למערך יש אלמנט נתון יחיד:

@Test הציבור בטל givenArrayAndValue_whenValueFoundInArray_thenCorrect () {String [] hamcrestMatchers = {"אוספים", "שעועית", "טקסט", "מספר"}; assertThat (hamcrestMatchers, hasItemInArray ("טקסט")); }

אנו יכולים גם להשתמש בהתאמה חלופית לאותה בדיקה:

@ מבחן בטל פומבי givenValueAndArray_whenValueIsOneOfArrayElements_thenCorrect () {String [] hamcrestMatchers = {"אוספים", "שעועית", "טקסט", "מספר"}; assertThat ("טקסט", isOneOf (hamcrestMatchers)); }

או שבכל זאת נוכל לעשות את אותו הדבר עם התאמה אחרת כך:

@Test הציבור בטל givenValueAndArray_whenValueFoundInArray_thenCorrect () {String [] array = new String [] {"אוספים", "שעועית", "טקסט", "מספר"}; assertThat ("שעועית", isIn (מערך)); }

אנו יכולים גם לבדוק אם המערך מכיל אלמנטים נתונים ללא קשר לסדר:

@Test הציבור בטל givenArrayAndValues_whenValuesFoundInArray_thenCorrect () {String [] hamcrestMatchers = {"אוספים", "שעועית", "טקסט", "מספר"}; assertThat (hamcrestMatchers, arrayContainingInAnyOrder ("שעועית", "אוספים", "מספר", "טקסט")); }

כדי לבדוק אם המערך מכיל אלמנטים נתונים אך בסדר הנתון:

@Test הציבור בטל givenArrayAndValues_whenValuesFoundInArrayInOrder_thenCorrect () {String [] hamcrestMatchers = {"אוספים", "שעועית", "טקסט", "מספר"}; assertThat (hamcrestMatchers, arrayContaining ("אוספים", "שעועית", "טקסט", "מספר")); }

כאשר שלנו אוסף הוא מַפָּה, אנו יכולים להשתמש בהתאמות הבאות בפונקציות המתאימות הללו:

כדי לבדוק אם הוא מכיל מפתח נתון:

@Test הציבור בטל givenMapAndKey_whenKeyFoundInMap_thenCorrect () {Map map = חדש HashMap (); map.put ("blogname", "baeldung"); assertThat (מפה, hasKey ("שם פרטי")); }

וערך נתון:

@Test הציבור בטל givenMapAndValue_whenValueFoundInMap_thenCorrect () {מפה מפה = HashMap חדש (); map.put ("blogname", "baeldung"); assertThat (map, hasValue ("baeldung")); }

ולבסוף ערך נתון (מפתח, ערך):

@Test הציבור בטל givenMapAndEntry_whenEntryFoundInMap_thenCorrect () {Map map = חדש HashMap (); map.put ("blogname", "baeldung"); assertThat (map, hasEntry ("blogname", "baeldung")); }

7. ה מספר שידוך

ה מספר התאמות משמשות לביצוע קביעות על משתנים של ה- מספר מעמד.

לבדוק גדול מ מַצָב:

@Test הציבור בטל givenAnInteger_whenGreaterThan0_thenCorrect () {assertThat (1, greaterThan (0)); }

לבדוק גדול מ אוֹ שווה ל מַצָב:

@Test הציבור בטל givenAnInteger_whenGreaterThanOrEqTo5_thenCorrect () {assertThat (5, largeThanOrEqualTo (5)); }

לבדוק פחות מ מַצָב:

@Test הציבור בטל givenAnInteger_whenLessThan0_thenCorrect () {assertThat (-1, lessThan (0)); }

לבדוק פחות מ אוֹ שווה ל מַצָב:

@Test public void givenAnInteger_whenLessThanOrEqTo5_thenCorrect () {assertThat (-1, lessThanOrEqualTo (5)); }

לבדוק קרוב ל מַצָב:

@ מבחן הריק ציבורי שניתן ADouble_whenCloseTo_thenCorrect () {assertThat (1.2, closeTo (1, 0.5)); }

בואו נשים לב מקרוב למשחק האחרון, קרוב ל. הטיעון הראשון, האופרנד, הוא זה שאליו משווים את היעד והטיעון השני הוא הסטייה המותרת מהאופראנד . משמעות הדבר היא שאם המטרה היא אופרנד + סטייה או סטיית אופרנד, אז הבדיקה תעבור.

8. התאמת הטקסטים

קביעה מופעלת חוּטs נעשה קל יותר, מסודר ואינטואיטיבי יותר עם המקרסטהתאמת טקסטים. אנו נסתכל עליהם בחלק זה.

כדי לבדוק אם א חוּט זה ריק:

@Test הציבור בטל givenString_whenEmpty_thenCorrect () {String str = ""; assertThat (str, isEmptyString ()); }

כדי לבדוק אם א חוּט ריק או ריק:

@Test הציבור בטל givenString_whenEmptyOrNull_thenCorrect () {String str = null; assertThat (str, isEmptyOrNullString ()); }

כדי לבדוק שוויון של שניים חוּטתוך התעלמות מהמרחב הלבן:

@Test הציבור בטל given2Strings_whenEqualRegardlessWhiteSpace_thenCorrect () {String str1 = "text"; מחרוזת str2 = "טקסט"; assertThat (str1, equalToIgnoringWhiteSpace (str2)); }

אנו יכולים גם לבדוק אם קיימת מחרוזת משנה אחת או יותר בנתון חוּט בסדר נתון:

@ מבחן חלל ציבורי givenString_whenContainsGivenSubstring_thenCorrect () {String str = "calligraphy"; assertThat (str, stringContainsInOrder (Arrays.asList ("call", "graph"))); }

לבסוף, אנו יכולים לבדוק שוויון בין שניים חוּטללא קשר למקרה:

@ מבחן ציבורי בטל given2Strings_whenEqual_thenCorrect () {String a = "foo"; מחרוזת b = "FOO"; assertThat (a, equalToIgnoringCase (b)); }

9. ממשק ה- API של Core

ה המקרסט API API הליבה אמור לשמש ספקי מסגרת של צד שלישי. עם זאת, זה מציע לנו כמה מבנים נהדרים כדי להפוך את מבחני היחידות לקריאים יותר וכמה התאמות ליבה שניתן להשתמש בהם באותה קלות.

קריאות עם הוא לבנות על גפרור:

@Test ציבורי בטל given2Strings_whenIsEqualRegardlessWhiteSpace_thenCorrect () {String str1 = "text"; String str2 = "text"; assertThat (str1, is (equalToIgnoringWhiteSpace (str2))); }

ה הוא לבנות על סוג נתונים פשוט:

@ מבחן בטל פומבי given2Strings_whenIsEqual_thenCorrect () {String str1 = "text"; מחרוזת str2 = "טקסט"; assertThat (str1, is (str2)); }

שלילה עם לֹא לבנות על גפרור:

@ מבחן ציבורי בטל given2Strings_whenIsNotEqualRegardlessWhiteSpace_thenCorrect () {String str1 = "text"; String str2 = "טקסטים"; assertThat (str1, not (equalToIgnoringWhiteSpace (str2))); }

ה לֹא לבנות על סוג נתונים פשוט:

@ מבחן ציבורי בטל given2Strings_whenNotEqual_thenCorrect () {String str1 = "text"; String str2 = "טקסטים"; assertThat (str1, not (str2)); }

בדוק אם א חוּט מכיל מחרוזת נתון:

@ מבחן חלל ציבורי שניתן AStrings_whenContainsAnotherGivenString_thenCorrect () {String str1 = "קליגרפיה"; String str2 = "call"; assertThat (str1, containString (str2)); }

בדוק אם א חוּט מתחיל במיתר משנה נתון:

@ מבחן ציבורי בטל שניתן AString_whenStartsWithAnotherGivenString_thenCorrect () {String str1 = "קליגרפיה"; String str2 = "call"; assertThat (str1, startsWith (str2)); }

בדוק אם א חוּט מסתיים במחרוזת נתון:

@ מבט פומבי בטל שניתן AString_whenEndsWithAnotherGivenString_thenCorrect () {String str1 = "קליגרפיה"; מחרוזת str2 = "phy"; assertThat (str1, endsWith (str2)); }

בדוק אם שניים לְהִתְנַגֵדהם מאותו מופע:

@ מבחן חלל ציבורי given2Objects_whenSameInstance_thenCorrect () {חתול חתול = חתול חדש (); assertThat (cat, sameInstance (cat)); }

בדוק אם לְהִתְנַגֵד הוא מופע של מחלקה נתונה:

@Test הציבור בטל givenAnObject_whenInstanceOfGivenClass_thenCorrect () {חתול חתול = חתול חדש (); assertThat (cat, instanceOf (Cat.class)); }

בדוק אם כל חברי א אוסף לעמוד בתנאי:

@Test public void givenList_whenEachElementGreaterThan0_thenCorrect () {List list = Arrays.asList (1, 2, 3); int baseCase = 0; assertThat (רשימה, everyItem (greaterThan (baseCase))); }

בדוק שא חוּט לא ריק:

@ מבחן חלל ציבורי givenString_whenNotNull_thenCorrect () {String str = "notnull"; assertThat (str, notNullValue ()); }

תנאי השרשרת יחד, הבדיקה עוברת כאשר היעד עומד באחד מהתנאים, בדומה ל OR לוגי:

@ מבט בטל פומבי givenString_whenMeetsAnyOfGivenConditions_thenCorrect () {String str = "קליגרפיה"; מחרוזת התחלה = "התקשר"; סוף מחרוזת = "foo"; assertThat (str, anyOf (startsWith (start), containString (end))); }

תנאי שרשרת יחד, הבדיקה עוברת רק כאשר היעד עומד בכל התנאים, בדומה ל- AND הגיוני:

@Test הציבור בטל givenString_whenMeetsAllOfGivenConditions_thenCorrect () {String str = "קליגרפיה"; מחרוזת התחלה = "התקשר"; מחרוזת סוף = "phy"; assertThat (str, allOf (startsWith (start), endsWith (end))); }

10. התאמה אישית

אנו יכולים להגדיר התאמה משלנו על ידי הרחבה TypeSafeMatcher. בחלק זה, ניצור התאמה מותאמת אישית המאפשרת לעבור את הבדיקה רק כאשר היעד הוא מספר שלם חיובי.

מחלקה ציבורית IsPositiveInteger מרחיב את TypeSafeMatcher {public void descriptionTo (תיאור התיאור) {description.appendText ("מספר שלם חיובי"); } @Factory התאמה סטטית ציבורית isAPositiveInteger () {להחזיר IsPositiveInteger חדש (); } התאמות בוליאניות מוגנות @ Override בטוח (מספר שלם שלם) {החזר שלם> 0; }}

אנחנו צריכים רק ליישם את התאמה בטוח שיטה שבודקת שהמטרה היא אכן מספר שלם חיובי וה- לתאר אל שיטה שמייצרת הודעת כשל במקרה שהבדיקה לא עוברת.

להלן מבחן המשתמש בהתאמה המותאמת אישית החדשה שלנו:

הריקון הציבורי של @Test givenInteger_whenAPositiveValue_thenCorrect () {int num = 1; assertThat (num, isAPositiveInteger ()); }

והנה הודעת כישלון שאנו מקבלים מאז שעברנו במספר שלם לא חיובי:

java.lang.AssertionError: צפוי: מספר שלם חיובי אבל: היה 

11. מסקנה

במדריך זה, יש לנו חקר את ה- API של Hamcrest ולמדנו כיצד אנו יכולים לכתוב איתו מבחני יחידות טובים יותר ומתוחזקים יותר.

היישום המלא של כל הדוגמאות וקטעי הקוד ניתן למצוא בפרויקט github של Hamcrest.


$config[zx-auto] not found$config[zx-overlay] not found