我正在使用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()
返回None,所以我认为我应该在运行此功能之前以某种方式设置请求上下文。
我试图做到这一点...
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)
答案 0 :(得分:0)
如果您确实要进行单元测试,则需要一次对一个功能进行单元测试。我认为这是真正的测试驱动开发。因此,首先编写用于创建的测试,然后加载。使用修补程序模拟对其他函数的调用功能。
答案 1 :(得分:0)
如果您正在编写单元测试,则使用模拟可能会有所帮助。对于带有flask-jwt-extended的jwt授权,您可以修补jwt_required decorator中调用的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。该代码可能会随新版本而更改。
答案 2 :(得分: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