4

我正在使用 JWT 授权创建一个 Flask 应用程序,并尝试使用 PyTest 测试服务。

我成功地将测试添加到端点,但是当我尝试为某些功能添加单元测试时,我无法访问当前用户,因为flask_jwt_extended.get_current_user()返回 None。

这是一个简单的例子:

@api.route('/listings', methods=['POST'])
@jwt_required
def create_listing():
    payload = request.json
    listing = listing_svc.create(payload)
    return listing


def create(payload):
    listing = ListingSchema().load(payload, db.session).data


class ListingSchema(ModelSchema):
    id = field_for(Project, 'id', dump_only=True)
    creator_user_id = field_for(Project, 'creator_user_id')
    # ...

    @pre_load
    def set_creator_id(self, data):
        current_user = flask_jwt_extended.get_current_user()
        data['creator_user_id'] = current_user.id

当我使用 app_context 授权和发送请求时,它可以工作:

with client.application.app_context():
    rv = client.post('/listings',
        # ...
    )

但我需要的是在create不向客户端发送请求的情况下测试功能。在这种情况下flask_jwt_extended.get_current_user()返回无,所以我认为我应该在运行这个函数之前以某种方式设置请求上下文。

我试着这样做...

fake_payload = {}
with client.application.test_request_context('/listings', headers={'Authorization': 'Bearer ' + access_token}):
    create(fake_payload)

但仍然得到current_user的是None

这就是我获得令牌的方式:

def login(email, password):
    user = get_by_email(email)
    if user and check_password_hash(user.password, password):
        return access_token = flask_jwt_extended.create_access_token(identity=email)
4

3 回答 3

2

如果您正在编写单元测试,使用模拟可能会有所帮助。对于使用 flask-jwt-extended 的 jwt 授权,您可以修补从jwt_required 装饰器verify_jwt_in_request调用的方法。然后,您还可以修补函数以返回测试用户名。例如:get_jwt_identity

from unittest.mock import patch


@patch('path.to.some.code.get_jwt_identity')
@patch('flask_jwt_extended.view_decorators.verify_jwt_in_request')
def test_some_code(mock_jwt_required, mock_jwt_identity):
    mock_jwt_identity.return_value = 'user1'

    # Test jwt protected endpoint

注意:此补丁特定于最新的软件包版本 flask-jwt-extended==3.21.0。代码可能会随着新版本的变化而变化。

于 2019-08-22T15:24:12.727 回答
0

很久以前的问题,但这里是更多读者的解决方案。

您需要激活 app_context,然后是 request_context,最后调用装饰器正在调用的函数,即verify_jwt_in_request


fake_payload = {}
with client.application.app_context():
    with client.application.test_request_context('/listings', headers={'Authorization': 'Bearer ' + access_token}):
        verify_jwt_in_request()
        create(fake_payload)

现在你有你的 current_user 集

于 2020-05-21T08:43:31.780 回答
-1

如果你真的想进行单元测试,你需要一次对一个函数进行单元测试。在我看来,这是真正的测试驱动开发。所以首先为创建编写测试然后加载等等。使用补丁来模拟调用其他函数的功能。

于 2019-06-20T16:11:28.493 回答