Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask test_client: Testing DELETE request with data

I'm trying to test my Flask app using suggestions from http://flask.pocoo.org/docs/testing/, but I couldn't figure out how to test DELETE method with form data.

My delete method looks something like this:

from flask.ext.restful import Resource, reqparse 
...
def delete(self):
    self.reqparse.add_argument('arg1', type=str, required=True, location='form')
    args = self.reqparse.parse_args()
    ...

I would like to test it with:

def setUp(self):
    self.app = myApp.app.test_client()

def test_delete(self):
    rv = self.app.delete('MyEndPoint', data={'arg1', 'val'})

But it doesn't work. I also looked at the source code of EnvironBuilder in werkzeug.test but still got no idea how to pass in the data.

like image 365
victorchen Avatar asked Jun 06 '14 02:06

victorchen


1 Answers

I just ran into the same issue, and this is basically because Werkzeug's test method does not currently support setting the content_type of DELETE requests.

The code here shows how Werkzeug gets the content type:

def _get_content_type(self):
    ct = self.headers.get('Content-Type')
    if ct is None and not self._input_stream:
        if self.method in ('POST', 'PUT', 'PATCH'):
            if self._files:
                return 'multipart/form-data'
            return 'application/x-www-form-urlencoded'
        return None
    return ct

If there's no content_type, then the form data never makes it out of the environ and into the request, so your Flask server doesn't actually get sent the data.

Ultimately, this is a bug with Werkzeug, as you can craft a curl request that uses a DELETE method and also includes form data. I've submitted a pull request to the Werkzeug repo to address this issue. Feel free to chime in on github: https://github.com/mitsuhiko/werkzeug/pull/620

Update: to actually solve your problem in the mean time, you can get around this by explicitly stating a content type in your request, like so:

def test_delete(self):
    rv = self.app.delete('MyEndPoint',
                         data={'arg1', 'val'},
                         headers={'Content-Type': 'application/x-www-form-urlencoded'})

Update again: The pull request I've submitted has been reviewed, refined, and merged, and will be included in the 0.10 release of Werkzeug, so hopefully this shouldn't be an issue anymore :)

like image 141
Kevin Avatar answered Nov 04 '22 04:11

Kevin