librelist archives

« back to archive

Flask Testing and Simulating RESTful requests

Flask Testing and Simulating RESTful requests

From:
Jesse Panganiban
Date:
2012-06-28 @ 22:10
Hey guys,

I've been trying to create a json POST request in flask's testing client 
and it turns out that it doesn't seem to acknowledge the 
('Content-Type', 'application/json') in the headers.

Code Sample:

Assumption: I have a controller that responds to '/persons and accepts 
GET and POST requests. When it receives a POST request, it tries to get 
the 'name' attribute from response.json object and then creates a 
database entry.

from myapp import app
import unittest
import json


class MyTestCase(unittest.TestCase):

     def setUp(self):
         app['TESTING'] = True
         self.app = app.test_client()

     def test_json_post(self):
         headers = [('Content-Type', 'application/json')]
         data = {'name': 'Jesse'}
         json_data = json.dumps(data)
         json_data_length = len(json_data)
         headers.append(('Content-Length', json_data_length))
         response = self.app.post('/persons', headers=headers, data)


What happens is I get a 500 error in the controller because the 
response.json object does not exist and I'm trying to extract data from 
it. Instead of getting the payload data in the response.json, it is 
loaded in the request.form.

Curl equivalent is:

curl -X POST -H "Content-Type: application/json" -d '{"name": "Jesse"}' 
localhost:5000/persons


Thanks,
Jesse

Fwd: Flask Testing and Simulating RESTful requests

From:
Jesse Panganiban
Date:
2012-06-29 @ 01:32
Here's an update,

I learned that you can set the content_type as a parameter in the 
test_client. It can now make a proper restful request properly:

@app.route('/persons', methods=['GET', 'POST'])
def api_persons():
     if request.method == 'GET':
         # GET STUFF HERE
     elif request.method == 'POST':
         # Even causes it to crash
         print request.json
         return ''
     else:
         return abort(405)


# Inside a test case where self.app = app.test_client()
def test_case(self):
     data = dict(name="Jesse")
     response = self.app.post('/persons', data=data, 
content_type='application/json')
     # Response returns a 400
     self.assertEqual(response.status_code, 200)

Now, the problem is that when trying to access the request.json object 
inside the app (view/controller), it immediately returns with an error 
(status 400)

Anyone having the same problems as mine?


-------- Original Message --------
Subject: 	Flask Testing and Simulating RESTful requests
Date: 	Fri, 29 Jun 2012 06:10:11 +0800
From: 	Jesse Panganiban <me@jpanganiban.com>
To: 	flask@librelist.com



Hey guys,

I've been trying to create a json POST request in flask's testing client
and it turns out that it doesn't seem to acknowledge the
('Content-Type', 'application/json') in the headers.

Code Sample:

Assumption: I have a controller that responds to '/persons and accepts
GET and POST requests. When it receives a POST request, it tries to get
the 'name' attribute from response.json object and then creates a
database entry.

from myapp import app
import unittest
import json


class MyTestCase(unittest.TestCase):

     def setUp(self):
         app['TESTING'] = True
         self.app = app.test_client()

     def test_json_post(self):
         headers = [('Content-Type', 'application/json')]
         data = {'name': 'Jesse'}
         json_data = json.dumps(data)
         json_data_length = len(json_data)
         headers.append(('Content-Length', json_data_length))
         response = self.app.post('/persons', headers=headers, data)


What happens is I get a 500 error in the controller because the
response.json object does not exist and I'm trying to extract data from
it. Instead of getting the payload data in the response.json, it is
loaded in the request.form.

Curl equivalent is:

curl -X POST -H "Content-Type: application/json" -d '{"name": "Jesse"}'
localhost:5000/persons


Thanks,
Jesse



Re: [flask] Fwd: Flask Testing and Simulating RESTful requests

From:
Simon Sapin
Date:
2012-06-29 @ 06:10
Le 29/06/2012 03:32, Jesse Panganiban a écrit :
> # Inside a test case where self.app = app.test_client()
> def test_case(self):
>      data = dict(name="Jesse")
>      response = self.app.post('/persons', data=data,
> content_type='application/json')
>      # Response returns a 400
>      self.assertEqual(response.status_code, 200)

Hi,

Try to use json.dumps(data) before passing in to the test client. The 
client usually encodes dicts in the k1=v1&k2=v2 format used by forms and 
may not check the passed content_type.

request.json probably fails because the request body is not in JSON 
format (and causes a parse error.)

Regards,
-- 
Simon Sapin