Listing Three显示了spec参数的另一种用法。这次,有带三个属性的类Foo(4~12行)。把类名传入构造器中,这样就产生了一个和Foo有相同属性的mock对象(18~23行)。再次,访问一个未声明的属性引发了AttributeError(29~32行)。也就是说,在两个例子中,方法属性时没有功能的。甚至在方法有功能代码时,调用mock的方法也什么都不做。
Listing Three
from mock import Mock
# The class interfaces
class Foo(object):
# instance properties
_fooValue = 123
def callFoo(self):
print "Foo:callFoo_"
def doFoo(self, argValue):
print "Foo:doFoo:input = ", argValue
# create the mock object
mockFoo = Mock(spec = Foo)
# accessing the mocked attributes
print mockFoo
# returns
print mockFoo._fooValue
# returns
print mockFoo.callFoo()
# returns:
mockFoo.callFoo()
# nothing happens, which is fine
# accessing the missing attributes
print mockFoo._fooBar
# raises: AttributeError: Mock object has no attribute '_fooBar'
mockFoo.callFoobar()
# raises: AttributeError: Mock object has no attribute 'callFoobar'
下一个构造器参数是return_value。这将设置mock对象的响应当它被直接调用的时候。我用这个参数模拟一个工厂调用。
为了演示,在Listing Four中,设置return_value为456(第4行)。当调用mockFoo时,将返回456的结果(9~11行)。在Listing Five中,我给return_value传入了一个类Foo的实例fooObj(15~19行)。现在,当我调用mockFoo时,我获得了fooObj的实例(显示为mockObj)(第24行)。和Listing Two和Three不一样,mockObj的方法是带有功能的。
Listing Four
from mock import Mock
# create the mock object
mockFoo = Mock(return_value = 456)
print mockFoo
#
mockObj = mockFoo()
print mockObj
# returns: 456
Listing Five
from mock import Mock
# The mock object
class Foo(object):
# instance properties
_fooValue = 123
def callFoo(self):
print "Foo:callFoo_"
def doFoo(self, argValue):
print "Foo:doFoo:input = ", argValue
# creating the mock object
fooObj = Foo()
print fooObj
# returns: <__main__.foo>
mockFoo = Mock(return_value = fooObj)
print mockFoo
# returns:
# creating an "instance"
mockObj = mockFoo()
print mockObj
# returns: <__main__.foo>
# working with the mocked instance
print mockObj._fooValue
# returns: 123
mockObj.callFoo()
# returns: Foo:callFoo_
mockObj.doFoo("narf")
# returns: Foo:doFoo:input = narf
side_effect参数和return_value是相反的。它给mock分配了可替换的结果,覆盖了return_value。简单的说,一个模拟工厂调用将返回side_effect值,而不是return_value。
Listing Six演示了side_effect参数的影响。首先,创建类Foo的实例fooObj,把它传入return_value参数(第17行)。这个结果和Listing Five是类似的。当它被调用的时候,mockFoo返回fooObj(第22行)。然后我重复同样的步骤,给side_effect参数传入StandardError(第28行),现在,调用mockFoo引发了StandardError,不再返回fooObj(29~30行)。