aiohttp unittest with URLs not GET

aiohttp unittest with URLs not GET

我试了一下 example in the aiohttp docs about unitttesting 以了解示例中发生的事情以及它是如何工作的。我想我仍然 误解了一些事情。

我需要“模拟”从 URL 下载 xml 或 html 文件。但是示例代码是关于 GET 方法的,因为它执行 router.add_get()。但是没有 router.add_url() 或类似的东西。

所以我的理解有误吗?

错误是

$ python3 -m unittest org.py
E
======================================================================
ERROR: test_example (org.MyAppTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/aiohttp/test_utils.py", line 439, in setUp
    self.app = self.loop.run_until_complete(self.get_application())
  File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/home/user/share/work/aiotest/org.py", line 16, in get_application
    app.router.add_get('https://whosebug.com', hello)
  File "/usr/local/lib/python3.9/dist-packages/aiohttp/web_urldispatcher.py", line 1158, in add_get
    resource = self.add_resource(path, name=name)
  File "/usr/local/lib/python3.9/dist-packages/aiohttp/web_urldispatcher.py", line 1071, in add_resource
    raise ValueError("path should be started with / or be empty")
ValueError: path should be started with / or be empty

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)

示例代码

#!/usr/bin/env python3
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
from aiohttp import web, ClientSession


class MyAppTestCase(AioHTTPTestCase):

    async def get_application(self):
        """
        Override the get_app method to return your application.
        """
        async def hello(request):
            return web.Response(text='Hello')

        app = web.Application()
        app.router.add_get('https://whosebug.com', hello)
        return app

    # the unittest_run_loop decorator can be used in tandem with
    # the AioHTTPTestCase to simplify running
    # tests that are asynchronous
    @unittest_run_loop
    async def test_example(self):
        async with ClientSession() as session:
            async with session.get('https://whosebug.com') as resp:
                assert resp.status == 200
                text = await resp.text()
                assert 'Hello' in text

编辑:我的 Python 是 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110] 并且 aiohttp 是 `3.7.4.post0' - 都来自 Debian 11(稳定)存储库。

您不能使用 aiohttp.web.Application() 路由器模拟特定地址。它希望您声明相对于应用程序根目录的路由,例如您提到的an example

class MyAppTestCase(AioHTTPTestCase):

    async def get_application(self):
        """
        Override the get_app method to return your application.
        """
        async def hello(request):
            return web.Response(text='Hello, world')

        app = web.Application()
        app.router.add_get('/', hello)
        return app

您应该使用 self.client 引用测试您在 get_application 方法中创建的应用程序并使用相对路径:

@unittest_run_loop
async def test_example(self):
    resp = await self.client.request("GET", "/")
    assert resp.status == 200
    text = await resp.text()
    assert "Hello, world" in text

或者(您可能真正想要的)使用 responses 库:

@responses.activate
def test_simple():
    responses.add(responses.GET, 'https://whosebug.com',
                  body='Hello', status=200)