python通过模拟测试装饰器
这个问题是Python中关于decorators的后续问题: 我使用给定的“代码片段使任何装饰程序一般地接受任何参数” 然后我有一个(这里是简化的)装饰器:python通过模拟测试装饰器,python,testing,mocking,decorator,Python,Testing,Mocking,Decorator,这个问题是Python中关于decorators的后续问题: 我使用给定的“代码片段使任何装饰程序一般地接受任何参数” 然后我有一个(这里是简化的)装饰器: @decorator\u带有参数 def拥有来自于(func,*args,**kwargs)的权限: “”“装饰程序检查kwarg的简单访问/查看权限。”“” def包装(*args_1,**kwargs_1): 如果kwargs_1中的“kwarg”: kwarg=kwargs_1['kwarg'] 其他: 引发HTTP403Error(
@decorator\u带有参数
def拥有来自于(func,*args,**kwargs)的权限:
“”“装饰程序检查kwarg的简单访问/查看权限。”“”
def包装(*args_1,**kwargs_1):
如果kwargs_1中的“kwarg”:
kwarg=kwargs_1['kwarg']
其他:
引发HTTP403Error()
返回函数(*args_1,**kwargs_1)
返回包装器
def测试\u can\u访问\u kwarg(自):
“”“测试简单权限装饰器。”“”
func=Mock(返回值=“确定”)
修饰的\u func=具有来自\u slug()的\u权限(func(kwarg=self.kwarg))
#它将在下面的线路上升起,而kwarg是提供的。。。
响应=修饰的函数()
self.assertTrue(函数调用)
self.assertEqual(响应“OK”)
decorated_func = has_permission_from_slug()(func(kwarg=self.kwarg))
这将:
func(kwarg=self.kwarg)
**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定义(没有更改)和链接答案中定义的带参数的
decorator\u
:
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异常。你好,谢谢你的回答!我以前应该说过,但我肯定也试过你的建议。不幸的是:第一个示例失败,因为response=decordent_func(kwarg=self.kwarg)
返回“TypeError:'str'object is not callable”。第二个示例可以工作,但不适合我的原始范围,因为我想测试一个在代码中使用kwargs_1工作的装饰程序。在上一个代码示例中有一个小错误,现在也可以了。虽然第一个解决方案以前是有效的,但第二个例子仍然不符合我的目的。第一个仍然失败。它的工作超出了kwarg检查,但在第行返回func(*args_1,**kwargs_1)
我的错误,实际上在通过给出参数func(kwarg=self.kwarg)测试调用之后,我让它像装饰的_func=has_permission_一样从_kwarg()(func())
调用函数!!!对不起。最后,还使用了Mock,这是您发布的第一个代码片段。谢谢你的帮助!