Reputation: 21
I am new to python and flask. I wanted to create unit tests for an api written. We have used jwt
for authentication.
To unit test, I don't want the flow to enter @jwt_required
decorator. In addition to that I have chained a few other decorators for that method.
class A():
@jwt_required()
@mandatory_fields_check
@unlock_and_lock()
def get(self, address, name):
..
..
..
return jsonify(
{"payload": data,
"message": "data received successfully"}), 200
Unit test I am trying to write
def test_get():
a_obj = A()
a_obj.get("address123", 'xyz')
When I run above test using py.test, I am getting Runtime error
def _find_app():
top = _app_ctx_stack.top
if top is None:
raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.
E
E This typically means that you attempted to use functionality that needed
E to interface with the current application object in some way. To solve
E this, set up an application context with app.app_context(). See the
E documentation for more information.
Below are my objectives:
I don't want flow to enter decorators logic
Jwt decorator is asking for context. However my intention is to unit test this method as a normal class method without any flask features.
How can I mock objects created inside the method under test?
Upvotes: 2
Views: 3972
Reputation: 8914
Instead of trying to mock the decorator, mock out the function the decorator is calling.
I ran into a similar obstacle using flask_jwt_extended where I wanted to mock out the jwt_required
decorator.
@jwt_required
def post(payload)
....
Instead of
mock.patch('flask_jwt_extended.jwt_required')
I looked at the function the jwt_required
decorator was calling (which in this case was verify_jwt_in_request
from flask_jwt_extended.view_decorators
). So,
mock.patch('flask_jwt_extended.view_decorators.verify_jwt_in_request')
did the trick!
Upvotes: 2
Reputation: 21
I used this library called undecorated and its working fine for me. https://stackoverflow.com/a/35418639
https://pypi.org/project/undecorated/
This is clean, however if there is a any easier way without importing libraries please suggest.
Upvotes: 0
Reputation: 2768
It should be like this, but not tested.
import mock
def mock_jwt_required(realm):
return
@mock.patch('flask_jwt.jwt_required', side_effect=mock_jwt_required)
def test_get(jwt_required_fn):
a_obj = A()
a_obj.get("address123", 'xyz')
Upvotes: 0