我正在尝试对我的RESTful API进行单元测试。这是我的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]
但是,这是我的问题:处理程序没有看到名称或描述参数。 :(
有什么建议吗?
答案 0 :(得分: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]
答案 1 :(得分:3)
假设您使用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
答案 2 :(得分:2)
put handler会解析request.body,如果请求有正确的内容类型标题(application / x-www-form-urlencoded),例如你正在使用tornado http client:
headers = HTTPHeaders({'content-type': 'application/x-www-form-urlencoded'})
http_client.fetch(
HTTPRequest(url, 'PUT', body=urllib.urlencode(body), headers=headers))
答案 3 :(得分:0)
您是否尝试过使用get
方法?因为根据您测试程序的方式,如果您通过Firefox或Chrome等浏览器进行测试,他们可能会这样做。 Doing a HTTP PUT from a browser
如果我是你,我会写get
而不是put
。因此,您肯定可以在浏览器中测试它。
例如,而不是:
def put ...
尝试:
def get ...
或实际上在你的:
name = self.get_argument('name', None)
description = self.get_argument('description', None)
为什么None
在那里?根据{{3}}:
RequestHandler.get_argument(name,default = [],strip = True)
...
如果未提供默认值,则认为该参数是必需的, 如果丢失,我们会抛出一个HTTP 400异常。
因此,在您的情况下,因为您没有提供正确的默认值,因此您的应用程序返回HTTP 400.错过默认值! (即)
name = self.get_argument('name')
description = self.get_argument('description')