Context: I have two Flask routes which process the same request data (one interactively, one as an API). To keep my code DRY, I want to write a function process_post_request()
that
- accepts the request as in input parameter from each route,
- parses the request,
- returns results which the routes can use.
For example, in views.py:
@app.route('/interactive', methods=['GET', 'POST'])
def interactive():
if request.method == 'POST':
sum, product = process_post_request(request)
# present the results on a web page
@app.route('/api', methods=['GET', 'POST'])
def api():
if request.method == 'POST':
sum, product = process_post_request(request)
# return the results so that JavaScript can parse them
def process_post_request(request):
param1 = request.form.get('param1')
param2 = request.form.get('param2')
sum = param1 param2
product = param1 * param2
return sum, product
Question: How can I write a pytest for process_post_request()
? The problem is that if I create a "request" and try to pass it to process_post_request()
, the request goes to a route, so that route returns a result. For example, in views_test.py:
import pytest
@pytest.fixture
def client():
"""Create a client to make requests from"""
with app.test_client() as client:
with app.app_context():
pass
yield client
def test_process_post_request():
request = client.post('/interactive', data={'param1': 5, 'param2': 7})
sum, product = process_post_request(request)
assert sum == 12
Because request
returns a response, pytest throws this error:
> request = client.post('/interactive', data={'param1': 5, 'param2': 7})
E AttributeError: 'function' object has no attribute 'post'
CodePudding user response:
I created an app route to return comma-separated parameters:
@app.route('/pass-through', methods = ['GET', 'POST'])
def pass_through():
if request.method == 'POST':
params = process_post_request(request)
return ','.join(params)
Then tested that app route:
def test_process_post_request():
with app.test_client() as client:
response = client.post('/pass-through', data={'param1': 5, 'param2': 7})
sum, product = response.data.decode().split(',')
assert sum == 12
where decode()
translates from bytes to string.
It's not the most satisfying solution because it really tests the app route, so it depends on the app route function pass_through()
using the same parameter names as process_post_request()
.