gpt4 book ai didi

python通过模拟测试装饰装饰器

转载 作者:行者123 更新时间:2023-11-28 17:49:14 24 4
gpt4 key购买 nike

这个问题是 this brilliant answer 的后续问题关于 Python 中的装饰器:

我使用给定的“片段让任何装饰器普遍接受任何参数”。

然后我有这个(这里是简化的)装饰器:

@decorator_with_args
def has_permission_from_kwarg(func, *args, **kwargs):
"""Decorator to check simple access/view rights by the kwarg."""
def wrapper(*args_1, **kwargs_1):
if 'kwarg' in kwargs_1:
kwarg = kwargs_1['kwarg']
else:
raise HTTP403Error()

return func(*args_1, **kwargs_1)

return wrapper
  1. 使用这个装饰器,没问题,它能很好地完成工作。
  2. 测试完全不需要 kwargs 的类似装饰器,结果相同。
  3. 但是用下面的 mock 测试这个装饰器是行不通的:

    def test_can_access_kwarg(self):
    """Test simple permission decorator."""
    func = Mock(return_value='OK')
    decorated_func = has_permission_from_slug()(func(kwarg=self.kwarg))
    # It will raise at the following line, whereas the kwarg is provided...
    response = decorated_func()
    self.assertTrue(func.called)
    self.assertEqual(response, 'OK')

它返回我在没有“kwarg”关键字参数时引发的异常...

有没有人知道如何测试(最好通过模拟)这样一个由另一个需要访问传递给函数的关键字参数之一的装饰器装饰的装饰器?

最佳答案

decorated_func = has_permission_from_slug()(func(kwarg=self.kwarg))

这将:

  1. 执行func(kwarg=self.kwarg)
  2. 生成实际装饰器的实例。
  3. 根据函数的结果调用装饰器-调用(即结果)。
  4. 返回包装器,稍后将尝试调用步骤 3 的结果(这会失败)。

    response = decorated_func()

这将调用返回的不带参数的包装器,因此 **kwargs_1 为空。此外,如果您的包装器在这种情况下不会引发异常,则 func(..) 的后续调用将引发异常,因为 func 的返回值(原始的)可能不可调用(见上文)。

你可能想要做的,或者至少你的装饰器支持的是:

decorated_func = has_permission_from_kwarg()(func)
response = decorated_func(kwarg=self.kwarg)

或者,如果你想像这样在装饰器中传递你的kwarg:

decorated_func = has_permission_from_kwarg(kwarg=self.kwarg)(func)
response = decorated_func()

然后您需要调整或装饰器以实际使用 kwargs,而不是在检查中使用 kwargs_1(后者是装饰函数的参数)。


我正在使用以下代码测试您的原始装饰器定义(没有更改)和链接答案中定义的 decorator_with_args:

class HTTP403Error (Exception):
pass

def func (*args, **kwargs):
print('func {}; {}'.format(args, kwargs))

my_kwarg = 'foo'
decorated_func = has_permission_from_kwarg()(func)
decorated_func(kwarg=my_kwarg)
decorated_func(not_kwarg=my_kwarg)

正如预期的那样,我得到了 func (); {'kwarg': 'foo'} 为第一个调用打印,为第二个调用打印 HTTP403 异常。

关于python通过模拟测试装饰装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13359727/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com