שלום לכולם! אחד האלמנטים המרכזיים בתאוריה של בדיקות קוד היא זו של חיקוי (Mocking). הכוונה היא ליצור אלמנט תכנותי שעבור הקוד הנבדק מתנהג כמו האלמנט הרגיל, אך למעשה אנו שולטים בו, ומכתיבים מה הוא יחזיר, ועוקבים אחריו.
כעת נניח שיש לנו קוד קיים שטוען מודול וקורא לאובייקטים ופונקציות ממנו: איך נוכל לעשות חיקוי של המודול מבלי לשנות את הקוד של המודול הנבדק? אני מימשתי קוד כזה בפרל כאן: http://search.cpan.org/src/SHLOMIF/SVN-RaWeb-Light-0.6.0/SVN/RaWeb/Light/Mock/CGI.pm השורה המשמעותית היא: BEGIN { $INC{'CGI.pm'} = "/usr/lib/perl5/site_perl/5.8.6/CGI.pm", } שגורמת למפרש לחשוב שהמודול כבר נטען. תהיתי איך אפשר לעשות זאת בפייתון. קראתי על כך שהפקודה import רושמת את המודול במשתנה sys.modules ולכן חיפשתי דרך לרשום שם מודול משלי. אחרי מספר נסיונות ודיבורים עם אנשים ב-IRC, הצלחתי לכתוב קוד הוכחת-היתכנות שמחקה את מודול cgi: <<<<<<<<<<<< import sys import new from StringIO import StringIO class cgi_param: def __init__(self, value): self.value = value def value(self): return self.value def get_params(): return {"hello":cgi_param("ShlomifTest")} cgi_mod = new.module("cgi"); cgi_mod.FieldStorage = get_params sys.modules['cgi'] = cgi_mod save_stdout = sys.stdout sys.stdout = StringIO() import mytestcgi buffer = sys.stdout.getvalue() sys.stdout = save_stdout if (buffer == "Content-Type: text/html\n\n\nShlomifTest\n"): print "ok" else: print "not ok: buffer == " + buffer >>>>>>>>>>>> מה שקורה הוא שכאשר טוענים את המודול "mytestcgi" אשר מכיל את הקוד, אז הוא קולט את המשתנים שאנו נותנים לו, ולא את מה שהמודול cgi האמיתי (שכלל לא נטען) נותן לו. בכבוד רב, שלומי פיש --------------------------------------------------------------------- Shlomi Fish [EMAIL PROTECTED] Homepage: http://www.shlomifish.org/ Tcl is LISP on drugs. Using strings instead of S-expressions for closures is Evil with one of those gigantic E's you can find at the beginning of paragraphs.