在单元测试中模拟认证装饰器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在单元测试中模拟认证装饰器相关的知识,希望对你有一定的参考价值。

我想在为其中一个视图编写单元测试时模拟validate_token装饰器

#views.py
from third_part.module import vaidate_token
from setting import config
class myViews:
     @validate_token([config['issuer'], config['secret_key']])
     def get_data():
         #Do stuff
         return json.loads(data)

这里validate_token是一个thirtd_party模块,用于授权请求,令牌由第三方发布,所以我不希望执行validate_token装饰器进行测试

下面是我的示例测试代码。

test_views.朋友

@patch('views.validate_token', lambda x: x)
def test_get_data(self):
    endpoint = '/app/get_data'
    res = self.client.get(endpoint)
    assert res.status_code==200

我试着在运行测试时进行模拟 但它没有按预期工作,它给出401错误。

我怎么能模拟/修补装饰器来测试这里缺少的东西

提前致谢。

答案

这里有一个可以帮助你的例子。下面的文件结构。

app.朋友

from flask import Flask
from third_part.example import validate_token

app = Flask(__name__)

@app.route('/')
@validate_token()
def index():
    return 'hi'

if __name__ == '__main__':
    app.run(debug=True)

/third_part/example.朋友

from functools import wraps

def validate_token():
    def validate(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            raise Exception('Token error. Just for example')
            return func(*args, **kwargs)
        return wrapper
    return validate

tests.朋友:

from app import app

app.testing = True

def test_index():
    with app.test_client() as client:
        client.get('/')

运行我们的tests.py(只需确保装饰器工作):

    @wraps(func)
    def wrapper(*args, **kwargs):
>       raise Exception('Token error. Just for example')
E       Exception: Token error. Just for example

第一种方法如何跳过装饰器(使用patch)。 tests.py:

from functools import wraps
from mock import patch

def mock_decorator():
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            return f(*args, **kwargs)
        return decorated_function
    return decorator

patch('third_part.example.validate_token', mock_decorator).start()
# !important thing - import of app after patch()
from app import app

app.testing = True

def test_index():
    with app.test_client() as client:
        client.get('/')

第二种方式(没有patch)。 tests.py:

from functools import wraps
from third_part import example

def mock_decorator():
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            return f(*args, **kwargs)
        return decorated_function
    return decorator
# !important thing - import of app after replace
example.validate_token = mock_decorator

from app import app
app.testing = True

def test_index():
    with app.test_client() as client:
        client.get('/')

运行我们的test.py(以两种方式):

tests.py .                                                               [100%]

=========================== 1 passed in 0.09 seconds ===========================

总结。如您所见,非常重要的是更换功能时。顺便说一句,你试图修补validate_token views模块,但不是third_part.module

希望这可以帮助。

以上是关于在单元测试中模拟认证装饰器的主要内容,如果未能解决你的问题,请参考以下文章

是否可以模拟打字稿装饰器?

如何在 Python 中模拟装饰器的内部调用

如何使用装饰器修补sys属性?

Python:如何在单元(鼻子)测试期间忽略装饰器?

Python 联合 - 在另一个装饰器中收集多个 @patch 装饰器

无效!有装饰器时不运行单元测试