使用Python mock监视对现有对象的调用

Nei*_*ais 28 python unit-testing mocking

我正在使用Python模拟模块进行测试.我想用模拟替换活动对象,并自动将对模拟对象的所有调用转发到原始对象.我认为这在标准测试术语中被称为"间谍".目前我正在测试中:

# Insert a mock replacement
orig_active_attr = server.active_attr
server.active_attr = mock.Mock()

# Set up side effects to 'proxy' to the original object
server.active_attr.meth1.side_effect = orig_active_attr.meth1
server.active_attr.meth2.side_effect = orig_active_attr.meth2

# Call the method being tested
server.method_being_tested()

# Assert stuff on the mock.
server.active_attr.meth2.assert_called_once()
Run Code Online (Sandbox Code Playgroud)

如果模拟的所有方法调用都可以在没有样板的情况下自动转发到活动对象,那将是很好的.

Nei*_*ais 25

我似乎偶然发现了解决方案:

import mock

class A(object):
    def meth(self, a):
        return a
a = A()
ma = mock.Mock(wraps=a)
Run Code Online (Sandbox Code Playgroud)

似乎可以正常使用函数,方法和属性,但不适用于类或实例属性.

请参阅文档.


Wil*_*hes 8

您可以patch.object(wraps=obj_instance)按照使用Python的模拟模块在实例方法上进行间谍活动中的建议使用。

例如:

from mock import patch

class Foo(object):
    def bar(self, x, y):
        return x + y + 1

def test_bar():
    foo = Foo()
    with patch.object(foo, 'bar', wraps=foo.bar) as wrapped_foo:
        foo.bar(1, 2)
        wrapped_foo.assert_called_with(1, 2)
Run Code Online (Sandbox Code Playgroud)

  • Python 3.5 添加了“wraps”。IMO 现在这应该是首选解决方案。 (2认同)