Proxies and Mocks in Python

Yesterday I wrote a post about using Proxy class in Java to create a trivial mock framework - creating the same thing in Python takes even fewer lines of code. The generic proxy can be implemented very easily as shown below.

class Proxy(object):
    def __init__(self,subject):
        self.subject=subject
        self.expectations={}
    def __getattr__(self,name):
        if self.expectations.__contains__(name):
            def wrap():
                return self.expectations[name]
            return wrap
        else:
            raise Exception("No expectations set on mock for this attribute")

    def expect(self,name,value): 
        if hasattr(self.subject,name): 
            self.expectations[name]=value 
        else: 
            raise Exception("No attribute with given name")

class Test(object): 
    def get_int(self): 
        return 12 
t=Test() 
print t.get_int() 
p=Proxy(t) 
print p 
try: 
    p.expect("unknown","value") 
except: 
    print "caught exception adding expectation on unknown method" 

p.expect("get_int",45) 
print p.get_int() 
try: 
    p.get_intxxx() 
except: 
    print "caught exception trying to call unknown attribute with no expectation"

And this produces the following output

Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>> 
12caugt exception adding expectation on unknown method
45
caught exception trying to call unknown attribute with no expectation
>>>
Written on June 19, 2012