python - Autospec "through"带有 unittest.mock 的装饰器

标签 python unit-testing mocking python-unittest

假设我有一个简单的装饰方法,如下所示:

def my_decorator(fn):
  def _wrapper(*args, **kwargs):
    print 'Calling decorated function'
    fn(*args, **kwargs)
  return _wrapper

class Foo(object):
  @my_decorator
  def incr(self, x):
    return x+1

装饰器“删除”方法签名以用于自动指定目的:

>>> mock_foo = mock.create_autospec(Foo, instance=True)
>>> mock_foo.incr(1, 2, 3, 4)
<MagicMock name='mock.incr()' id='23032592'>

这应该会提高:

TypeError: <lambda>() takes exactly 2 arguments (5 given)

由于关键字参数中的拼写错误,我遇到过这样的错误。

有什么方法可以编写装饰器(或给 autospec 一个“提示”)以便捕获这些类型的错误?

最佳答案

我认为 autospec 不能直接做到这一点。不过,您可以在装饰器中进行一些修改,以便可以测试未装饰的函数。如果您让装饰器保存对未装饰函数的引用:

def my_decorator(fn):
  def _wrapper(*args, **kwargs):
    print 'Calling decorated function'
    fn(*args, **kwargs)
  _wrapper._orig = fn
  return _wrapper

您可以通过模拟的装饰函数访问它:

>>> mock_incr = mock.create_autospec(Foo.incr)
>>> mock_incr(1,3,4,5,5)               # Decorated function doesn't fail.
<MagicMock name='mock()' id='8734864'>
>>> mock_incr._orig(1,3,4,5,5)         # But the original does, which is what we want
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib64/python2.6/site-packages/mock.py", line 954, in __call__
    _mock_self._mock_check_sig(*args, **kwargs)
TypeError: <lambda>() takes exactly 3 arguments (6 given)
>>> mock_incr._orig(1,3)
<MagicMock name='mock._orig()' id='8739664'>

但是,如果您自动指定整个实例,则这不起作用。不知道为什么。

>>> mock_foo = mock.create_autospec(Foo, instance=True)
>>> mock_foo.incr(1,3,4,5)             # We expect this to not raise an exception
<MagicMock name='mock.incr2()' id='8758416'>
>>> mock_foo.incr._orig(1,3,4,5)       # But we were hoping this would :(
<MagicMock name='mock.incr._orig()' id='8740624'>

还值得注意的是Venusian ,这可以改变装饰器绑定(bind)到装饰方法的方式,专门解决这个用例。不过,可能比您想要的更重量级。

关于python - Autospec "through"带有 unittest.mock 的装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24042546/

相关文章:

c# - 单元测试。为什么 Mock 在第二次循环迭代中返回不同的值?

c# - 无法在单元测试中将 void 分配给隐式类型变量

javascript - 模拟测试 http - angular2

c++ - CMake:尝试将链接库添加到未在此目录中构建的目标

python - 替换字符串中的子字符串

值超过阈值时的python平均数组(如果平均)

python - 最小最大图像直方图拉伸(stretch)

python - 使用 Matplotlib 和 TeX 统一间距

unit-testing - tdd - 为第 3 方代码创建测试

Django 测试客户端意外重定向