回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我有一个Sanic应用程序,可以对外部api进行异步调用。我希望编写一些模拟这些外部调用的单元测试。在</p>
<p>在下面的代码中,我们可以从日志中看到测试通过了。但是,在它们完成一个RuntimeError之后:抛出这个已经在运行的事件循环</p>
<p>简化的Sanic应用程序:</p>
<pre><code>app = Sanic(__name__)
app.config.from_pyfile('/usr/src/app/config.py')
Initialize(
app,
access_token_name='jwt',
authenticate=lambda: True,
claim_aud=app.config.AUTH_JWT_TOKEN['service']['audience'],
claim_iss=app.config.AUTH_JWT_TOKEN['service']['issuer'],
public_key=app.config.AUTH_JWT_TOKEN['service']['secret'],
responses_class=JWTResponses
)
@app.listener('before_server_start')
def init(app, loop):
ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_ctx.load_cert_chain(app.config.SSL_CERT, app.config.SSL_CERT_KEY)
ssl_ctx.load_verify_locations(app.config.SSL_SERVER_CERT)
ssl_ctx.check_hostname = False
ssl_ctx.verify_mode = ssl.CERT_REQUIRED
conn = aiohttp.TCPConnector(ssl_context=ssl_ctx)
app.aiohttp_session = aiohttp.ClientSession(loop=loop, connector=conn)
access_logger.disabled = True
@app.listener('after_server_stop')
def finish(app, loop):
loop.run_until_complete(app.aiohttp_session.close())
loop.close()
@app.route("endpoint/<mpn>")
@protected()
async def endpoint(request, mpn):
msg = msg(
mpn,
)
headers = {'content-type': 'text/xml'}
async with session.post(
config.URL,
data=msg.tostring(pretty_print=True, encoding='utf-8'),
headers=headers,
) as response:
response_text = await response.text()
try:
response = (
Response.from_xml(response_text)
)
return response
except ResponseException:
logger.error(e.get_message()['errors'][0]['message'])
return response.json(
e.get_message(),
status=HTTPStatus.INTERNAL_SERVER_ERROR
)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000)
</code></pre>
<p>测试如下:</p>
^{pr2}$
<p>如上所述,测试确实通过,但随后抛出错误。在</p>
<pre><code>================================================================================================= ERRORS ==================================================================================================
____________________________________________________________________________________ ERROR at teardown of test_success ____________________________________________________________________________________
tp = <class 'RuntimeError'>, value = None, tb = None
def reraise(tp, value, tb=None):
try:
if value is None:
value = tp()
if value.__traceback__ is not tb:
raise value.with_traceback(tb)
> raise value
/usr/local/lib/python3.6/site-packages/six.py:693:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python3.6/site-packages/six.py:693: in reraise
raise value
/usr/local/lib/python3.6/site-packages/six.py:693: in reraise
raise value
/usr/local/lib/python3.6/site-packages/pytest_sanic/plugin.py:212: in sanic_client
loop.run_until_complete(client.close())
uvloop/loop.pyx:1451: in uvloop.loop.Loop.run_until_complete
???
/usr/local/lib/python3.6/site-packages/pytest_sanic/utils.py:230: in close
await self._server.close()
/usr/local/lib/python3.6/site-packages/pytest_sanic/utils.py:134: in close
await trigger_events(self.after_server_stop, self.loop)
/usr/local/lib/python3.6/site-packages/pytest_sanic/utils.py:25: in trigger_events
result = event(loop)
server.py:84: in finish
loop.run_until_complete(app.aiohttp_session.close())
uvloop/loop.pyx:1445: in uvloop.loop.Loop.run_until_complete
???
uvloop/loop.pyx:1438: in uvloop.loop.Loop.run_until_complete
???
uvloop/loop.pyx:1347: in uvloop.loop.Loop.run_forever
???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E RuntimeError: this event loop is already running.
uvloop/loop.pyx:448: RuntimeError
</code></pre>
<p>如有任何帮助或建议,我们将不胜感激。提前谢谢</p>