【问题标题】:How to call mocked method in Python mock如何在 Python 模拟中调用模拟方法
【发布时间】:2015-08-23 13:04:16
【问题描述】:

我想创建一个模拟方法来调用被模拟的底层方法。

我在想像下面这样的事情,但我找不到任何关于持有对被模拟对象的引用的模拟对象的文档,我在下面将其表示为[[wrapped_method_foo]]

from mock import patch

class Foo(object):
    def __init__(self, state):
        self.state = state
    def foo(self, a):
        print "real foo", a
        return a + self.state

f = Foo(2000)
f.foo(1)

with patch.object(Foo, 'foo', autospec=True) as mock_foo:
    def side_effect(self, a):
        print "mock foo", a
        return mock_foo.[[wrapped_method_foo]](self, a*2)
    mock_foo.side_effect = side_effect

    f.foo(2)

【问题讨论】:

    标签: python unit-testing mocking python-mock


    【解决方案1】:

    最简单的方法是在修补之前获取您自己对原始函数的引用。可以在类的单个实例上进行修补:

    original_foo = f.foo
    with patch.object(f, 'foo') as mock_foo:
        def side_effect(a):
            print "mock foo", a
            return original_foo(a*2)
        mock_foo.side_effect = side_effect
    
        f.foo(2)
    

    ...或通过修补类上的未绑定方法:

    original_foo = Foo.foo
    with patch.object(Foo, 'foo', autospec=True) as mock_foo:
        def side_effect(self, a):
            print "mock foo", a
            return original_foo(self, a*2)
        mock_foo.side_effect = side_effect
    
        f.foo(3)
    

    【讨论】:

    • 谢谢艾琳。我不得不稍作修改才能让它工作。但是,我开始怀疑我最初打算以这种方式使用模拟对象是否是个好主意。
    【解决方案2】:

    补丁对象有一个你可以使用的未记录的temp_original 属性。

    在这种情况下,我通常会这样做:

    from __future__ import print_function
    import mock
    
    class Foo(object):
        def __init__(self, state):
            self.state = state
    
        def foo(self, a):
            print("real foo", a)
            return a + self.state
    
    
    f = Foo(2000)
    f.foo(1)
    
    fake_foo = mock.patch.object(Foo, 'foo', autospec=True)
    # def side_effect(*args, **kwargs):  # generic version
    def side_effect(self, a):
        print("mock foo", a)
        return fake_foo.temp_original(self, a*2)
    
    with fake_foo as mock_foo:
        mock_foo.side_effect = side_effect
    
        assert f.foo(2) == 2004
    

    当我只使用 mock 来断言测试期间调用的函数时,我会使用它

    【讨论】:

    • 为什么不使用记录在案的mock.DEFAULT 属性? docs.python.org/3/library/…
    • @asmaier 我不知道。我猜文档很混乱? DEFAULT 值似乎是……各种方法的默认值。我做了一些测试,但无法按照您的意思进行操作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 2013-09-12
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多