TEST RESTful PUT handler method does not receive request arguments

I am trying to unit test my RESTful API. Here is my API:

class BaseHandler(tornado.web.RequestHandler): def __init__(self, *args, **kwargs): tornado.web.RequestHandler.__init__(self, *args, **kwargs) self.log = self.application.log self.db = self.application.db class ProductHandler(BaseHandler): @tornado.web.removeslash def put(self, id = None, *args, **kwargs): try: self.log.info("Handling PUT request") if not id: raise Exception('Object Id Required') id = { '_id' : id } new_values = dict() name = self.get_argument('name', None) description = self.get_argument('description', None) if name: new_values['name'] = name if description: new_values['description'] = description self.db.products.update(id, new_values, safe = True) except: self.log.error("".join(tb.format_exception(*sys.exc_info()))) raise class Application(tornado.web.Application): def __init__(self, config_path, test = False, *args, **kwargs): handlers = [ (r"/product/?(.*)", ProductHandler), ] settings = dict(debug=True) tornado.web.Application.__init__(self, handlers, **settings) self.log = logging.getLogger(__name__) self.config = ConfigParser() self.config.read(config_path) self.mongo_connection = Connection( host = self.config.get('mongo','host'), port = self.config.getint('mongo','port'), ) if test: db_name = self.config.get('test', 'mongo.db') else: db_name = self.config.get('mongo', 'db') self.log.debug("Using db: %s" % db_name) self.db = self.mongo_connection[db_name] 

But here is my problem: the handler does not see the arguments of the name or description. :(

Any suggestions?

+4
source share
4 answers

As a job, I found them in request.body and analyzed the encoded parameters manually. It was annoying, but it works.

 new_values = urlparse.parse_qs(self.request.body) # values show as lists with only one item for k in new_values: new_values[k] = new_values[k][0] 
+4
source

Let's say if you use jQuery to send this PUT request:

 $.ajax({ type: "PUT", url: "/yourURL", data: JSON.stringify({'json':'your json here'), dataType: 'json' }) 

data should not look like this: data: {'json': 'your json here'}, , because it will be automatically encoded into the query string, which should be parse_qs parsed

Then to tornado

 def put(self, pid): d = json.loads(self.request.body) print d 
+3
source

put handler will parse request.body if the request has the correct content type header (application / x-www-form-urlencoded), for example, if you use the tornado http client:

 headers = HTTPHeaders({'content-type': 'application/x-www-form-urlencoded'}) http_client.fetch( HTTPRequest(url, 'PUT', body=urllib.urlencode(body), headers=headers)) 
+2
source

Have you tried using the get method? Because depending on how you test your program, if you test it through a browser, such as Firefox or Chrome, they will be able to do it. Executing HTTP PUT from a browser

If I were you, I would write get instead of put . You can check it in your browser.

For example, instead of:

 def put ... 

Try:

 def get ... 

Or actually in your:

 name = self.get_argument('name', None) description = self.get_argument('description', None) 

Why is there None ? According to the documentation :

RequestHandler.get_argument (name, default = [], strip = True)

...

If no default value is specified, the argument is considered mandatory, and we will throw an HTTP 400 exception if it is missing.

So, in your case, because you do not provide the proper one by default, therefore your application returns HTTP 400. Skip the default task! (I.e.)

 name = self.get_argument('name') description = self.get_argument('description') 
0
source

All Articles