使用pythonmock模块,我如何修补一个类,使它只存根我想要存根的方法,而不去管其他属性和方法?
我想做的是在一个类中存根几个方法,这些方法在我正在测试的代码中被间接实例化。我希望该修补类的所有其他属性和方法都能正常工作 下面是一个简单的例子,展示了我想要的东西(Python2.7)。(注意:在我的实际用例中,MyClass是一个在我正在测试的某些代码中间接实例化的类): 结果:使用pythonmock模块,我如何修补一个类,使它只存根我想要存根的方法,而不去管其他属性和方法?,python,unit-testing,mocking,Python,Unit Testing,Mocking,我想做的是在一个类中存根几个方法,这些方法在我正在测试的代码中被间接实例化。我希望该修补类的所有其他属性和方法都能正常工作 下面是一个简单的例子,展示了我想要的东西(Python2.7)。(注意:在我的实际用例中,MyClass是一个在我正在测试的某些代码中间接实例化的类): 结果: $ python mock_test.py Traceback (most recent call last): File "mock_test.py", line 27, in <module>
$ python mock_test.py
Traceback (most recent call last):
File "mock_test.py", line 27, in <module>
assert my_instance.unmocked() == 'unmocked', my_instance.unmocked()
AssertionError: <MagicMock name='MyClass().unmocked()' id='140400215338448'>
$python mock_test.py
回溯(最近一次呼叫最后一次):
文件“mock_test.py”,第27行,在
断言my_instance.unmocked()=='unmocked',my_instance.unmocked()
断言者错误:
为什么
unmocked
方法现在返回MagicMock
对象?我怎样才能修补这个类,使它只存根我想要的方法,而不去管其他的方法呢?你应该使用修补程序修补你的类。多个:
import mock
patcher = mock.patch.multiple(
'__main__.MyClass',
foo=mock.Mock(return_value='mocked foo!'),
bar=mock.Mock(return_value='bar')
)
使用上述代码更新代码后,它将运行,并且所有断言都将通过。下面是一个完整的工作示例:
from mock import patch, Mock
class MyClass(object):
def __init__(self):
self.prop = 'prop'
def foo(self):
return 'foo'
def bar(self):
return 'bar'
def unmocked(self):
return 'unmocked'
patcher = patch.multiple('__main__.MyClass',
foo=Mock(return_value='mocked foo!'),
bar=Mock(return_value='mocked bar!'))
patcher.start()
my_instance = MyClass()
assert my_instance.foo() == 'mocked foo!', my_instance.foo()
assert my_instance.bar() == 'mocked bar!', my_instance.bar()
assert my_instance.unmocked() == 'unmocked', my_instance.unmocked()
assert my_instance.prop == 'prop', my_instance.prop
patcher.stop()
您可以直接模拟所需的方法
,而不是使用patch.object来模拟整个类
如果我需要模拟多个方法怎么办?在这种情况下,比如说,foo
和bar
,而不影响prop
?@klenwell:这也是可能的。我已将答案更新为使用mock.patch.multiple
,它允许您在一次呼叫中修补多个内容。谢谢。这对我有用。我将更新我的问题以澄清这一期望。AttributeError:“dict”对象没有“return\u value”属性@Gang:您不需要混淆我示例中的MockedClass
。只需调用patcher.start()
。我已经更新了Simeon的答案,包含了完整的代码。
from mock import patch, Mock
class MyClass(object):
def __init__(self):
self.prop = 'prop'
def foo(self):
return 'foo'
def bar(self):
return 'bar'
def unmocked(self):
return 'unmocked'
patcher = patch.multiple('__main__.MyClass',
foo=Mock(return_value='mocked foo!'),
bar=Mock(return_value='mocked bar!'))
patcher.start()
my_instance = MyClass()
assert my_instance.foo() == 'mocked foo!', my_instance.foo()
assert my_instance.bar() == 'mocked bar!', my_instance.bar()
assert my_instance.unmocked() == 'unmocked', my_instance.unmocked()
assert my_instance.prop == 'prop', my_instance.prop
patcher.stop()
from mock import patch
class MyClass(object):
def __init__(self):
self.prop = 'prop'
def foo(self):
return 'foo'
def bar(self):
return 'bar'
patcher = patch.object(MyClass,"foo",return_value='mocked foo!')
MockedClass = patcher.start()
my_instance = MyClass()
assert my_instance.foo() == 'mocked foo!', my_instance.foo()
# These asserts will fail
assert my_instance.bar() == 'bar', my_instance.bar()
assert my_instance.prop == 'prop', my_instance.prop
patcher.stop()