aiohttp unittest模拟外部URL下载触发路径格式报错如何解决?
错误原因
aiohttp.web.Application的路由系统仅用于注册当前web服务的本地请求路径,要求路径必须以/开头,不支持直接绑定完整外部域名URL。你对router.add_get的功能存在理解偏差:该方法是为自身web服务添加接口路由,作用是处理发往当前服务的请求,不能拦截发往外部第三方服务的请求。
正确实现方案
根据你的测试需求,推荐两种实现方式:
方案1:使用aioresponses拦截请求(推荐)
无需启动额外web服务,直接拦截ClientSession发往指定外部URL的请求并返回自定义响应,适配硬编码外部URL的业务代码场景:
#!/usr/bin/env python3 import unittest from aiohttp import ClientSession from aioresponses import aioresponses class MyAppTestCase(unittest.IsolatedAsyncioTestCase): async def test_example(self): # 拦截指定URL的GET请求,返回自定义响应 with aioresponses() as mock_resp: mock_resp.get( 'https://stackoverflow.com', status=200, text='Hello' ) async with ClientSession() as session: async with session.get('https://stackoverflow.com') as resp: assert resp.status == 200 text = await resp.text() assert 'Hello' in text
方案2:使用aiohttp自带测试工具
如果不想引入第三方依赖,可把测试服务作为模拟的外部服务使用,请求时调用测试框架提供的客户端访问本地测试服务:
#!/usr/bin/env python3 from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop from aiohttp import web class MyAppTestCase(AioHTTPTestCase): async def get_application(self): async def hello(request): return web.Response(text='Hello') app = web.Application() # 仅注册本地路径,不要填写完整外部URL app.router.add_get('/', hello) return app @unittest_run_loop async def test_example(self): # 调用测试框架内置客户端访问本地测试服务 resp = await self.client.get('/') assert resp.status == 200 text = await resp.text() assert 'Hello' in text
如果你的业务代码中硬编码了外部URL,可在测试时将域名配置项替换为测试服务的本地地址即可。
内容的提问来源于stack exchange,提问作者buhtz
相关产品推荐
相关产品推荐

