5

RESTfulAPIをユニットテストしようとしています。これが私の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]                    

しかし、ここに私の問題があります:ハンドラーは名前または説明の引数を見ていません。:(

助言がありますか?

4

4 に答える 4

4

回避策として、request.body でそれらを見つけ、エンコードされたパラメーターを手動で解析しました。ちょっと面倒でしたが、うまくいきます。


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]             
于 2012-08-14T23:21:27.563 に答える
2

put handler will parse request.body, if request had proper content-type header (application/x-www-form-urlencoded), for example if you are using tornado http client:

headers = HTTPHeaders({'content-type': 'application/x-www-form-urlencoded'})
http_client.fetch(
      HTTPRequest(url, 'PUT', body=urllib.urlencode(body), headers=headers))
于 2014-02-12T09:02:36.450 に答える
2

jQuery を使用してこの PUT リクエストを送信するとします。

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

のようであってdataはなりません: data: {'json': 'your json here'},parse_qs によって解析される必要があるクエリ文字列に自動的にエンコードされるためです。

その後トルネードで

def put(self, pid):
    d = json.loads(self.request.body)
    print d
于 2013-08-23T20:37:53.897 に答える
0

get代わりにメソッドを使用してみましたか? プログラムのテスト方法によっては、Firefox や Chrome などのブラウザでテストすると、プログラムを実行できる可能性があります。ブラウザから HTTP PUT を実行する

私があなただったら、get代わりに書くだろうput. そうすれば、ブラウザで間違いなくテストできます。

たとえば、次の代わりに:

def put ...

試す:

def get ...

または実際にあなたの:

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

なぜNoneそこにあるのですか?ドキュメントによると:

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

...

デフォルトが指定されていない場合、引数は必須であると見なされ、欠落している場合は HTTP 400 例外がスローされます。

あなたの場合、適切なデフォルトを提供していないため、アプリは HTTP 400 を返しています。デフォルトを見逃してください! (すなわち)

name = self.get_argument('name')                                                                          
description = self.get_argument('description') 
于 2012-08-14T23:00:30.380 に答える