2015-12-29 56 views
3

我想要做的是存根類中的一些方法,這得到了一些代碼,我測試中間接實例。我希望修補類的所有其他屬性和方法正常工作。使用Python模擬模塊,我該如何修補一個類,以便它僅保留我想要存根的方法並保留其他屬性和方法?

這裏有一個簡單的例子,顯示了我想要的(Python 2.7版)。 (注:在我的實際使用情況,MyClass的是,得到了一些代碼中間接實例類我測試):

from mock import patch 

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('__main__.MyClass') 
MockedClass = patcher.start() 
instance = MockedClass.return_value 
instance.foo.return_value = 'mocked foo!' 
instance.bar.return_value = 'mocked bar!' 

my_instance = MyClass() 
assert my_instance.foo() == 'mocked foo!', my_instance.foo() 
assert my_instance.bar() == 'mocked bar!', my_instance.bar() 

# These asserts fail 
assert my_instance.unmocked() == 'unmocked', my_instance.unmocked() 
assert my_instance.prop == 'prop', my_instance.prop 

patcher.stop() 

結果:

$ 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'> 

爲什麼unmocked方法現在返回MagicMock對象?我該如何修補這個課程,以便它只保留我想要的方法並讓其他所有方面獨立?

回答

4

你應該使用patch.multiple修補類:

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() 
+0

全班method如果我需要模擬比一個方法的更多?在這種情況下,比如'foo'和'bar'不影響'prop'? – klenwell

+0

@klenwell:那也是可以的。我已經更新了使用'mock.patch.multiple'的答案,允許您在一次調用中修補多個事物。 –

+0

謝謝。這對我有效。我會更新我的問題以澄清這一期望。 – klenwell

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

您可以直接嘲笑你想要的,而不是使用patch.object

相關問題