如何在Python中调用类的方法时捕获字段值?

时间:2015-06-12 18:52:17

标签: python unit-testing mocking

我有一个奇怪的第三方库,要求我执行以下操作(从该库导入A):

def foo(my_props):
  a = A()
  a.props = my_props
  a.post()

所以我想要的是确保在调用a.post()时,props的{​​{1}}设置正确。请注意,这是一个非常简化的示例,因此显然很容易模拟foo。不幸的是,还有更多内容(例如my_props可能会在调用foo之前在a.post中进行修改。

值得注意的是,通过查看该导入的源代码,props不是类属性。这是一个简单的dict类字段,在类self.props = ...中的随机位置设置类似A的内容。

那么如何设置我的嘲讽来完成这个盛宴呢?我甚至对post本身都不感兴趣。我需要知道调用delete的次数以及当时设置的值props

编辑:重新执行@hspandher响应,最后执行了以下操作,因为不幸的是call_args仍然是空的,我希望我可以在通话后进行分析。

@mock.patch('A.props', return_value=mock.PropertyMock())
def test_foo(self, mock_props):
    call_args = []
    def capture(*args, **kwargs):
        call_args.append(args)

    mock_props.__set__ = functools.partial(capture)

    a = A()
    a.foo()

    # analyze call_args...

2 个答案:

答案 0 :(得分:1)

为此你甚至不需要嘲笑,假设foo是在文件code.py中定义的,在测试文件中代码应该是这个from code import A A.props = <mockvalue>然后你的测试代码。但是如果你想做一些像嘲笑帖子那样更复杂的东西,我建议你使用python mock或fudge library

答案 1 :(得分:0)

如果您可以在a之外初始化foo并传递参数,那么实际调用如下所示:

def foo(my_props, obj):
    obj.props = my_props
    obj.post()

foo({'bar': 'baz'}, a)

然后你可以这样测试:

def test_foo():
    a = mock.create_autospec(A)
    foo(1, a)
    assert a.props == 1
    assert a.mock_calls == [mock.call.post()]

在调用props之前检查post是否已设置是多一点工作 您需要将foo转换为课程Foo

class Foo(object):

    def foo(self, my_props, obj):
        self._setup_props(my_props, obj)
        self._post(obj)

    def _setup_props(self, my_props, obj):
        obj.props = my_props

    def _post(self, obj):
        obj.post()

现在您可以模拟Foo本身及其foo方法来检查mock_calls订单:

>>> f = mock.Mock(spec=Foo, foo=Foo.foo)
>>> f.foo(f, 1, 2)
>>> f.mock_calls
[call._setup_props(1, 2), call._post(2)]