使用pytest_asyncio异步测试时遇TypeError:协程不支持异步上下文管理器
问题根源
你遇到的TypeError是因为:aiohttp.ClientSession.get()返回的是异步上下文管理器对象,必须实现__aenter__和__aexit__异步方法才能被async with使用。但你的测试里直接让mock_get返回了mock_response,导致async with试图把协程对象当作上下文管理器,触发了类型错误。
修复方案
修改测试中的mock逻辑,让mock_get返回一个模拟的异步上下文管理器,这个管理器的__aenter__方法返回你定义好的mock_response:
@pytest.mark.asyncio async def test_fetch_success(url_fetcher): # 模拟响应对象 mock_response = AsyncMock() mock_response.status = 200 mock_response.text.return_value = 'Mock Content' mock_response.raise_for_status.return_value = None # 补上业务代码里调用的raise_for_status方法 # 创建模拟的异步上下文管理器,__aenter__返回响应对象 mock_get_context = AsyncMock() mock_get_context.__aenter__.return_value = mock_response # 让session.get返回这个上下文管理器 mock_get = AsyncMock(return_value=mock_get_context) with patch('aiohttp.ClientSession.get', new=mock_get): content = await url_fetcher.fetch('http://example.com') assert content == 'Mock Content' mock_get.assert_called_once_with( 'http://example.com', headers=url_fetcher.headers, proxy=url_fetcher.proxy, timeout=10 )
额外提示
- 必须模拟
response.raise_for_status()方法,否则业务代码执行到这一步时会因为找不到该方法的实现报错。 - 你的
session_managerfixture已经处理了关闭逻辑,这部分无需调整。
内容的提问来源于stack exchange,提问作者Yonatan Levin
相关产品推荐
相关产品推荐

