Tornado 测试中只能执行 GET 请求
Can only perform GET requests in Tornado test
我正在尝试测试使用 asyncio 和新 async def
语法的 Tornado 请求处理程序。 GET 请求似乎有效,但其他请求失败。
import asyncio
import tornado.platform.asyncio as tasyncio
from tornado import testing
from tornado import web
class Handler(web.RequestHandler):
async def post(self):
await asyncio.sleep(1)
self.write('spam')
get = put = post
class HandlerTest(testing.AsyncHTTPTestCase):
def get_app(self):
return web.Application([('/', Handler)])
def get_new_ioloop(self):
return tasyncio.AsyncIOMainLoop()
def test_get(self):
response = self.fetch('/', method='GET')
self.assertEqual(b'spam', response.body)
def test_put(self):
response = self.fetch('/', method='PUT')
self.assertEqual(b'spam', response.body)
def test_post(self):
response = self.fetch('/', method='POST')
self.assertEqual(b'spam', response.body)
当 运行 交互式解释器中的处理程序时,它工作正常:
>>> app = web.Application([('/', Handler)])
>>> tornado.platform.asyncio.AsyncIOMainLoop().install()
>>> app.listen(8080)
<tornado.httpserver.HTTPServer object at 0x7fbf290f3fd0>
>>> asyncio.get_event_loop().run_forever()
所以我的问题是;如何使用 unittest 测试 Tornado/asyncio 请求处理程序的 POST 方法?
您的代码在 fetch
中缺失 body
,甚至是空的。 post/put 请求需要它 - 我在底部附上了工作代码。
fetch
(stop/wait) 似乎隐藏了有意义的错误。对于测试,我已将其更改为通用异步测试:
from tornado.testing import gen_test
class HandlerTest(testing.AsyncHTTPTestCase):
def get_app(self):
return web.Application([('/', Handler)])
def get_new_ioloop(self):
return tasyncio.AsyncIOMainLoop()
@gen_test
def test_put(self):
response = yield self.http_client.fetch(self.get_url('/'), method='PUT')
self.assertEqual(b'spam', response.body)
产生正确的错误
======================================================================
ERROR: test_put (__main__.HandlerTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/t35/lib/python3.5/site-packages/tornado/testing.py", line 132, in __call__
result = self.orig_method(*args, **kwargs)
File "/tmp/t35/lib/python3.5/site-packages/tornado/testing.py", line 525, in post_coroutine
timeout=timeout)
File "/tmp/t35/lib/python3.5/site-packages/tornado/ioloop.py", line 453, in run_sync
return future_cell[0].result()
File "/tmp/t35/lib/python3.5/site-packages/tornado/concurrent.py", line 232, in result
raise_exc_info(self._exc_info)
File "<string>", line 3, in raise_exc_info
File "/tmp/t35/lib/python3.5/site-packages/tornado/gen.py", line 1014, in run
yielded = self.gen.throw(*exc_info)
File "/tmp/t35/lib/python3.5/types.py", line 179, in throw
return self.__wrapped.throw(tp, *rest)
File "test.py", line 35, in test_put
response = yield self.http_client.fetch(self.get_url('/'), method='PUT')
File "/tmp/t35/lib/python3.5/site-packages/tornado/gen.py", line 1008, in run
value = future.result()
File "/tmp/t35/lib/python3.5/site-packages/tornado/concurrent.py", line 232, in result
raise_exc_info(self._exc_info)
File "<string>", line 3, in raise_exc_info
File "/tmp/t35/lib/python3.5/site-packages/tornado/stack_context.py", line 314, in wrapped
ret = fn(*args, **kwargs)
File "/tmp/t35/lib/python3.5/site-packages/tornado/gen.py", line 264, in <lambda>
future, lambda future: callback(future.result()))
File "/tmp/t35/lib/python3.5/site-packages/tornado/simple_httpclient.py", line 353, in _on_connect
('not ' if body_expected else '', self.request.method))
ValueError: Body must not be None for method PUT (unless allow_nonstandard_methods is true)
----------------------------------------------------------------------
Ran 1 test in 0.008s
工作代码:
import tornado.platform.asyncio as tasyncio
from tornado import testing
from tornado import web
class Handler(web.RequestHandler):
async def post(self):
await asyncio.sleep(0.1)
self.write('spam')
get = put = post
class HandlerTest(testing.AsyncHTTPTestCase):
def get_app(self):
return web.Application([('/', Handler)])
def get_new_ioloop(self):
return tasyncio.AsyncIOMainLoop()
def test_get(self):
response = self.fetch('/', method='GET')
self.assertEqual(b'spam', response.body)
def test_put(self):
response = self.fetch('/', method='PUT', body=b'')
self.assertEqual(b'spam', response.body)
def test_post(self):
response = self.fetch('/', method='POST', body=b'')
self.assertEqual(b'spam', response.body)
import unittest
unittest.main()
我正在尝试测试使用 asyncio 和新 async def
语法的 Tornado 请求处理程序。 GET 请求似乎有效,但其他请求失败。
import asyncio
import tornado.platform.asyncio as tasyncio
from tornado import testing
from tornado import web
class Handler(web.RequestHandler):
async def post(self):
await asyncio.sleep(1)
self.write('spam')
get = put = post
class HandlerTest(testing.AsyncHTTPTestCase):
def get_app(self):
return web.Application([('/', Handler)])
def get_new_ioloop(self):
return tasyncio.AsyncIOMainLoop()
def test_get(self):
response = self.fetch('/', method='GET')
self.assertEqual(b'spam', response.body)
def test_put(self):
response = self.fetch('/', method='PUT')
self.assertEqual(b'spam', response.body)
def test_post(self):
response = self.fetch('/', method='POST')
self.assertEqual(b'spam', response.body)
当 运行 交互式解释器中的处理程序时,它工作正常:
>>> app = web.Application([('/', Handler)])
>>> tornado.platform.asyncio.AsyncIOMainLoop().install()
>>> app.listen(8080)
<tornado.httpserver.HTTPServer object at 0x7fbf290f3fd0>
>>> asyncio.get_event_loop().run_forever()
所以我的问题是;如何使用 unittest 测试 Tornado/asyncio 请求处理程序的 POST 方法?
您的代码在 fetch
中缺失 body
,甚至是空的。 post/put 请求需要它 - 我在底部附上了工作代码。
fetch
(stop/wait) 似乎隐藏了有意义的错误。对于测试,我已将其更改为通用异步测试:
from tornado.testing import gen_test
class HandlerTest(testing.AsyncHTTPTestCase):
def get_app(self):
return web.Application([('/', Handler)])
def get_new_ioloop(self):
return tasyncio.AsyncIOMainLoop()
@gen_test
def test_put(self):
response = yield self.http_client.fetch(self.get_url('/'), method='PUT')
self.assertEqual(b'spam', response.body)
产生正确的错误
======================================================================
ERROR: test_put (__main__.HandlerTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/t35/lib/python3.5/site-packages/tornado/testing.py", line 132, in __call__
result = self.orig_method(*args, **kwargs)
File "/tmp/t35/lib/python3.5/site-packages/tornado/testing.py", line 525, in post_coroutine
timeout=timeout)
File "/tmp/t35/lib/python3.5/site-packages/tornado/ioloop.py", line 453, in run_sync
return future_cell[0].result()
File "/tmp/t35/lib/python3.5/site-packages/tornado/concurrent.py", line 232, in result
raise_exc_info(self._exc_info)
File "<string>", line 3, in raise_exc_info
File "/tmp/t35/lib/python3.5/site-packages/tornado/gen.py", line 1014, in run
yielded = self.gen.throw(*exc_info)
File "/tmp/t35/lib/python3.5/types.py", line 179, in throw
return self.__wrapped.throw(tp, *rest)
File "test.py", line 35, in test_put
response = yield self.http_client.fetch(self.get_url('/'), method='PUT')
File "/tmp/t35/lib/python3.5/site-packages/tornado/gen.py", line 1008, in run
value = future.result()
File "/tmp/t35/lib/python3.5/site-packages/tornado/concurrent.py", line 232, in result
raise_exc_info(self._exc_info)
File "<string>", line 3, in raise_exc_info
File "/tmp/t35/lib/python3.5/site-packages/tornado/stack_context.py", line 314, in wrapped
ret = fn(*args, **kwargs)
File "/tmp/t35/lib/python3.5/site-packages/tornado/gen.py", line 264, in <lambda>
future, lambda future: callback(future.result()))
File "/tmp/t35/lib/python3.5/site-packages/tornado/simple_httpclient.py", line 353, in _on_connect
('not ' if body_expected else '', self.request.method))
ValueError: Body must not be None for method PUT (unless allow_nonstandard_methods is true)
----------------------------------------------------------------------
Ran 1 test in 0.008s
工作代码:
import tornado.platform.asyncio as tasyncio
from tornado import testing
from tornado import web
class Handler(web.RequestHandler):
async def post(self):
await asyncio.sleep(0.1)
self.write('spam')
get = put = post
class HandlerTest(testing.AsyncHTTPTestCase):
def get_app(self):
return web.Application([('/', Handler)])
def get_new_ioloop(self):
return tasyncio.AsyncIOMainLoop()
def test_get(self):
response = self.fetch('/', method='GET')
self.assertEqual(b'spam', response.body)
def test_put(self):
response = self.fetch('/', method='PUT', body=b'')
self.assertEqual(b'spam', response.body)
def test_post(self):
response = self.fetch('/', method='POST', body=b'')
self.assertEqual(b'spam', response.body)
import unittest
unittest.main()