使用pythonmock模块,我如何修补一个类,使它只存根我想要存根的方法,而不去管其他属性和方法?

使用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>

我想做的是在一个类中存根几个方法,这些方法在我正在测试的代码中被间接实例化。我希望该修补类的所有其他属性和方法都能正常工作

下面是一个简单的例子,展示了我想要的东西(Python2.7)。(注意:在我的实际用例中,MyClass是一个在我正在测试的某些代码中间接实例化的类):

结果:

$ 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()