מה זה Moq ?

Monad Maybe

New member
תשובה

לרוב moq עושה את העבודה של הדמייה מעין dummy object,
השימוש שלו בא , בunit testing בתכנות בשימוש ב-tdd paradigm ולא רק.
מה האפשרויות:
בדיקת Routing
בדיקת DomainModel Repositories
בדיקת Multi Threading

מאפשר לדמות הכל, כולל Views/Pages/PartialViews/UserControls

אני מקווה שהייתי ברור , בהצלחה.

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

The Plumber

New member
כלי חזק ליצירת אובייקטים מדומים(mock objects)

משמש ככלי עזר לבדיקות תוכנה, בעיקר unit tests.

- השרברב
 
תודה, למדתי את הנושא של moq,

ועכשיו יש לי שאלה אחרת בנושא.
בסרט שראיתי, הוא מדגים איך הוא מחליף את MembershipService, FormsAuthentication, בקלאסים מזוייפים, ובעזרת המוק הוא "אומר" להם מה צריכה להחזיר כל מתודה כשיתנו לה פרמטרים מסוימים.
אז זה עובד, והטסט עובר, סבבה. אבל מה שקורה פה שאתה לא באמת בודק את כל התהליך. ואם תעשה מוק לכל הקלאסים הכבדים שלך, אלה שעושים את העבודה, מה בדקת פה?
איך צריך לבדוק אפליקציה שכל עניינה דטבייסים?
לדוגמה, איך לבדוק הוספה של יוזר? לעשות מוק זה לא לעניין, כי אז אתה לא באמת בודק את המנגנון. ואם תוסיף יוזר קבוע, hard coded, הוא יכשל בפעם השניה על כפילות במייל. (המייל הזה כבר מופיע לנו במערכת...). אז מה עושים?
והאם נכונה ההתרשמות שלי שביוניט טסטינג מקובל בעצם לעקוף את הגישה לDB ולא לבצע אותה בבדיקה, אלא לזייף באמצעות מוק?
 
תלוי מה ה scope של הבדיקה

ה scope של unit test הוא, ובכן, ה unit. כלומר ה"יחידה", שזה בד"כ מחלקה או פונקציה.
השימוש ב mocking framework, כמו moq, מאפשר לדמות אינטראקציה עם רכיבים או מחלקות שהם חיצוניים ליחידה הנבדקת.
לפיכך, כמו שכבר ציינת, מקובל ב UT לא לבצע את הגישה ל DB בבדיקה של לוגיקה עסקית, למשל.
בדיקות אינטגרציה הן בדיקות עם scope רחב יותר, שם בהחלט מקובל לכתוב נתונים ל DB ולוודא, למשל, שהם נכתבו ע"י שליפה מרכיב נוסף במערכת. אבל אלה כבר בדיקות אינטגרציה, כאמור, ולא UT.
אאל"ט יש אפשרות לבצע בדיקות אינטגרציה שמחזירות את ה DB לאיזה מצב התחלתי בין בדיקה לבדיקה, ע"י עטיפה בטרנזקציה (ואח"כ rollback מן הסתם). אני *חושב* שזה הדיפולט ב RoR, אגב (לא בטוח).
HTH
 

Miki Watts

New member
דרך אגב, שימוש ב Mock יכול לאפשר לך לדוגמה

לבדוק איך המערכת שלך מתנהגת במקרה שהיא באה לשמור יוזר והוא כבר קיים (מה שהמוק מדווח).
 

Monad Maybe

New member
לדוגמא אחרת

אם אתה מנסה לייצר route חכם ואתה צריך לדבאג אותו לצורך בדיקות אבטחה, moq ייצר לך context שאותו מקבל בglobal.asax .
דוגמא אחרת אתה רוצה לעשות בדיקות ב-views איך יתנהג הקונטרולר כאשר תכניס נתונים לא תקינים לתוך שדות טקסט, בנוסף בדיקת וולידציאות אפילו בקליינט.
 

Dizzy Doop

New member
אתה שואל שאלה

שכל מתכנת שואל את עצמו שכשהוא בה לכתוב בדיקות אוטומטיות לרכיבי התוכנה שבנה (אלא אם הוא עבד בTDD, שם הUT נכתבים מראש).

השאלה היא: "האם כדאי לי לכתוב בדיקות יסודיות שיכסו כל רכיב ורכיב שכתבתי בנפרד או שעדיף לי כבר לכסות את כל הרכיבים בעת ובעונה אחת ע"י בדיקה כוללת שתבדוק את תקינות המערכת כולה?".

ההחלטה לרוב תלויה בכמות הזמן שיש לך להשקיע כרגע, בכמות הקוד שכתבת ועד כמה הקוד שכתבת הוא טסטבילי באותו הזמן. ככל שהקוד פחות טסטבילי, קשה יותר לכתוב UT שיכסה אותו (כאשר למשל, בקוד של הטסט, אתה מוצא את עצמך צריך לחפור עכשיו בספריה של ה Reflection בחיפושך אחר דרך לזייף איזשהו משתנה private בתוך איזשהו class או אובייקט, או לחילופין לבצע refactoring לקוד באופן שיאפשר לך לבדוק אותו). אם זה לא מסתדר, אתה נשאר עם אופציה אחרת של בדיקת אינטגרציה, באופן שבו הטסט שלך הוא למעשה מבחינה לוגית איזשהו קליינט שעובד מול המערכת כולה (הסרבר) ששולח אליה בכל פעם input-ים שונים ובוחן הפלט המוחזר.
 

dixie chick

New member
MOQ זאת ספריה שבאמצעותה אפשר לכתוב חיקויים

לClassים
השימוש שלה הוא באמת בUnit Testings.
בדיקות UT כשמן כן הן- בדיקת יחידה, הרעיון הוא לא לבדוק תהליך שלם, אלא יחידת עבודה סגורה, לכן כשאני משתמשת ביחידה מסויימת בשירותים של יחידה אחרת (סגורה גם היא)- אני רוצה לעשות הפרדה ברורה בין שתי היחידות, ולבדוק כל אחת בנפרד.
אני לא רוצה להיות תלויה בתוצאות של יחידה אחרת כשאני בודקת יחידה מסויימת. (למשל- דמיין שיש באג שמפיל טסט, והטסט בודק יחידה א' שמשתמשת ביחידה ב', איפה הבאג שמפיל את הטסט? באיזה יחידה? איך אני אוכל לדעת עכשו מה שהשתנה? ונניח שהמורכבות עלתה ויחידה א' משתמשת ב20 יחידות אחרות? או שיחידה א' משתמשת ביחידה ב' ויחידה ב' משתמשת ביחידה ג'? איפה הבאג? את כולן אני אצטרך ליצור באמת כדי לבדוק משהו? את כל המערכת בעצם?)
ולכן באמצעות שימוש בספריית MOCKים (כמו MOQ, אגב אני אישית הרבה יותר מחבבת ספריה שנקראת FakeItEasy), אני יוצרת בידוד, אני יוצרת באמת את הUNIT שאני רוצה לבדוק, ואת שאר הUNITים שהיחידה שלי משתמשת בהם אני "מזייפת" (ומזייפת בהתאם את הקריאות למתודות ואת מה הן אמורות להחזיר), כך אני לא תלויה במצב המציאותי שלהם אלא אך ורק במצב המציאותי של היחידה שאותה אני באמת בודקת.
אגב גם כאן אני יכולה לוודא שלמשל הקריאה למתודה מסויימת בערך "מזוייף" קוראת מהיחידה שלי עם הפרמטרים הנכונים, ושאכן קוראת קריאה מסויימת ולא נגיד קריאה למתודה אחרת לגמרי, אלו דברים שהן כן בשליטת היחידה שלי ויש לי כלים לאכוף אותם.
 
תודה, הסבר טוב.

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

Miki Watts

New member
במצב כזה אין לך באמת לוגיקה

unit test אכן מיועד לבדוק לוגיקה במערכת בנפרד מתלויות אחרות, מה שמתאפשר ע"י mock.

אבל לדוגמה, בדקת מה קורה אם בסיס הנתונים מחזיר שגיאה ?
 

Dizzy Doop

New member
במקרה שלך, אני מציע

במקום UT, נסה דווקא להתחיל מלהוסיף לוגים למערכת שלך (באצמעות ספריה פופלארית כלשהי כמו MS Logging Application Block או log4net).

תמיד תוכל לכתוב integration tests שיקראו לאתר שלך באמצעות בקשת http (בכל פעם עם input-ים שונים) ולאחר מכן יעברו אוטומטית על הלוגים לראות שהכל בסדר (שלא נרשם לך error log איפשהו).
 
למעלה