שימוש מתקדם ב- JMockit

1. הקדמה

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

  • מזויף (או ללעוג API)
  • ה דה-קפסולציה מחלקת שירות
  • כיצד ללעוג ליותר מממשק אחד תוך שימוש במוק אחד בלבד
  • כיצד לעשות שימוש חוזר בציפיות ובאימותים

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

2. תלות של Maven

ראשית, נצטרך להוסיף את התלות ב- jmockit לפרויקט שלנו:

 org.jmockit jmockit 1.41 

לאחר מכן נמשיך בדוגמאות.

3. שיטות פרטיות / שיעורים פנימיים ללעג

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

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

עם JMockit יש לך שתי אפשרויות להתמודד עם אלה:

  • ה ללעוג ממשק API לשינוי היישום האמיתי (במקרה השני)
  • ה דה-קפסולציה מחלקת שירות, להתקשר ישירות לכל שיטה (במקרה הראשון)

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

מחלקה ציבורית AdvancedCollaborator {int i; private int privateField = 5; // קונסטרוקטור ברירת מחדל הושמט מתקדם AdvancedCollaborator (מחרוזת מחרוזת) זורק חריג {i = string.length (); } method String StringThatCallsPrivateMethod (int i) {return privateMethod () + i; } public int methodThatReturnsThePrivateField () {להחזיר privateField; } פרטי מחרוזת privateMethod () {return "default:"; } מחלקה InnerAdvancedCollaborator {...}}

3.1. מזייפים ללעוג

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

בואו נראה איך נוכל להגדיר מחדש privateMethod () באמצעות ה- API של Mockup:

@RunWith (JMockit.class) מחלקה ציבורית AdvancedCollaboratorTest {@Tested פרטית AdvancedCollaborator לעג; @Test בטל ציבורי testToMockUpPrivateMethod () {MockUp new () {@Mock private String privateMethod () {return "mocked:"; }}; מחרוזת res = mock.methodThatCallsPrivateMethod (1); assertEquals ("לעג: 1", res); }}

בדוגמה זו אנו מגדירים חדש ללעוג בשביל ה משתף פעולה מתקדם בשיעור באמצעות @לִלְעוֹג ביאור על שיטה עם חתימה תואמת. לאחר מכן, שיחות לשיטה זו יועצבו לשליחה שלנו.

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

@Test בטל ציבורי מבטToMockUpDifficultConstructor () זורק חריג {חדש MockUp () {@Mock ציבורי בטל $ init (קריאת קריאה, מחרוזת מחרוזת) {((AdvancedCollaborator) קריאה. GetInvokedInstance ()). I = 1; }}; AdvancedCollaborator coll = AdvancedCollaborator חדש (null); assertEquals (1, coll.i); }

בדוגמה זו, אנו יכולים לראות כי ללעוג לבנאי אתה צריך ללעוג ל init שיטה. אתה יכול להעביר טיעון נוסף מסוג קְרִיאָה, בעזרתו תוכל לגשת למידע על הפעלת השיטה הלעגנית, כולל המופע אליו מבוצעת הפנייה.

3.2. משתמש ב דה-קפסולציה מעמד

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

אתה יכול להפעיל שיטה:

@Test ציבורי בטל testToCallPrivateMethodsDirectly () {ערך אובייקט = Deencapsulation.invoke (מדומה, "privateMethod"); assertEquals ("ברירת מחדל:", ערך); }

ניתן גם להגדיר שדות:

@Test ציבורי בטל testToSetPrivateFieldDirectly () {Deencapsulation.setField (מדומה, "privateField", 10); assertEquals (10, mock.methodThatReturnsThePrivateField ()); }

וקבל שדות:

@Test בטל ציבורי testToGetPrivateFieldDirectly () {int value = Deencapsulation.getField (מדומה, "privateField"); assertEquals (5, value); }

וצור מקרים חדשים של שיעורים:

@Test מבטל הריק @ToCreateNewInstanceDirectly () {AdvancedCollaborator coll = Deencapsulation .newInstance (AdvancedCollaborator.class, "foo"); assertEquals (3, coll.i); }

אפילו מקרים חדשים של שיעורים פנימיים:

@Test מבטל בטל ציבוריToCreateNewInnerClassInstanceDirectly () {InnerCollaborator inner = Deencapsulation .newInnerInstance (InnerCollaborator.class, mock); assertNotNull (פנימי); }

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

4. ללעוג לממשקים מרובים באותו דמות אחת

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

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

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

לדוגמא, אנו הולכים ליצור דמה לממשקים רשימה ו ניתן להשוות שתי דרכים:

@RunWith (JMockit.class) מחלקה ציבורית AdvancedCollaboratorTest> {@Mocked MultiMock פרטית MultiMock; @Test ציבורי בטל testOnClass () {ציפיות חדשות () {{multiMock.get (5); תוצאה = "foo"; multiMock.compareTo ((רשימה) כל אחד); תוצאה = 0; }}; assertEquals ("foo", multiMock.get (5)); assertEquals (0, multiMock.compareTo (ArrayList חדש ())); } הציבור @ מבחן > בטל testOnMethod (@ Mocked M mock) {ציפיות חדשות () {{mock.get (5); תוצאה = "foo"; mock.compareTo ((List) any); תוצאה = 0; }}; assertEquals ("foo", mock.get (5)); assertEquals (0, mock.compareTo (ArrayList חדש ())); }}

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

בשורות מ 7 עד 18 אנו יכולים לראות דוגמה באמצעות דמה של ריבוי כיתות שהוגדרו לכל כיתת הבדיקה.

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

5. שימוש חוזר בציפיות ובאימותים

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

אנו נסביר זאת בדוגמה (אנו משתמשים בשיעורים מודל, משתף פעולה, ו שַׂחְקָן ממאמר JMockit 101 שלנו:

@RunWith (JMockit.class) כיתה ציבורית ReusingTest {@Injectable Private Collaborator משתף פעולה; דגם מודל פרטי של Mocked; @ שחקן פרפורמר פרטי שנבדק; @ לפני התקנת החלל הציבורי () {New Expectations () {{model.getInfo (); תוצאה = "foo"; minTimes = 0; collaborator.collaborate ("foo"); תוצאה = נכון; minTimes = 0; }}; } @Test ציבורי בטל testWithSetup () {performer.perform (דגם); VerifiedTrueCalls (1); } VerifiedTrueCalls (int שיחות) מוגן ריקות {Verifications new () {{collaborator.receive (true); זמנים = שיחות; }}; } TrueCallsVerification בכיתה הסופית מרחיב אימות {TrueCallsVerification ציבורי (שיחות int) {collaborator.receive (true); זמנים = שיחות; }} @Test חלל ציבורי testWithFinalClass () {performer.perform (model); TrueCallsVerification חדש (1); }}

בדוגמה זו תוכלו לראות בשורות 15 עד 18 שאנחנו מכינים ציפייה לכל מבחן כך model.getInfo () תמיד חוזר "פו" ועבור משתף פעולה.שיתוף פעולה() תמיד לצפות "פו" כוויכוח וחוזר נָכוֹן. שמנו את minTimes = 0 הצהרה כך שלא יופיעו כישלונות כאשר לא משתמשים בהם בפועל במבחנים.

כמו כן, יצרנו שיטה verifyTrueCalls (int) כדי לפשט את האימות למערכת משתף פעולה. קבל (בוליאני) השיטה כאשר הטיעון שהועבר הוא נָכוֹן.

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

6. מסקנה

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

אנו עשויים לעשות מאמרים נוספים על JMockit, לכן הישאר מעודכן כדי ללמוד עוד יותר.

וכמו תמיד, ניתן למצוא את היישום המלא של מדריך זה ב- GitHub.

6.1. מאמרים בסדרה

כל מאמרי הסדרה:

  • JMockit 101
  • מדריך לציפיות JMockit
  • שימוש מתקדם ב- JMockit

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