Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python通过模拟测试装饰器_Python_Testing_Mocking_Decorator - Fatal编程技术网

python通过模拟测试装饰器

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(

这个问题是Python中关于decorators的后续问题:

我使用给定的“代码片段使任何装饰程序一般地接受任何参数”

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

@decorator\u带有参数
def拥有来自于(func,*args,**kwargs)的权限:
“”“装饰程序检查kwarg的简单访问/查看权限。”“”
def包装(*args_1,**kwargs_1):
如果kwargs_1中的“kwarg”:
kwarg=kwargs_1['kwarg']
其他:
引发HTTP403Error()
返回函数(*args_1,**kwargs_1)
返回包装器
  • 和这个装饰师一起工作,没问题,它做得很好
  • 测试一个类似的装饰,不需要绝对的kwargs,同样的结果
  • 但使用以下模拟测试此装饰器不起作用:

    def测试\u can\u访问\u kwarg(自):
    “”“测试简单权限装饰器。”“”
    func=Mock(返回值=“确定”)
    修饰的\u func=具有来自\u slug()的\u权限(func(kwarg=self.kwarg))
    #它将在下面的线路上升起,而kwarg是提供的。。。
    响应=修饰的函数()
    self.assertTrue(函数调用)
    self.assertEqual(响应“OK”)
    
  • 当我没有'kwarg'关键字参数时,它返回我正在引发的异常

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

    decorated_func = has_permission_from_slug()(func(kwarg=self.kwarg))
    
    这将:

  • 执行
    func(kwarg=self.kwarg)
  • 生成实际装饰器的实例
  • 对func-调用的结果调用装饰程序(即结果)
  • 返回包装器,该包装器稍后将尝试调用步骤3中的结果(这将失败)

    响应=修饰的函数()

  • 然后,这将调用返回的包装,而不带任何参数,因此
    **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,这是您发布的第一个代码片段。谢谢你的帮助!