Python 3.7环境下AsyncMock的可替代方案有哪些?
Python 3.7 缺少 AsyncMock 的两种可用解决方案
AsyncMock 是 Python 3.8 才加入 unittest.mock 的内置类,Python 3.7 环境下可以通过以下两种方案解决:
方案1:使用官方向后移植的 mock 库(无代码侵入)
官方已经将包括 AsyncMock 在内的新版 mock 功能向后移植到了独立的 PyPI 包中,完美兼容 Python 3.7。
- 安装依赖:执行命令
pip install mock - 修改导入语句:将原代码中
from unittest import mock替换为import mock,其余代码不需要改动
修改后的测试代码如下:
import mock @mock.patch( "project.celerytasks.embedder.BulkEmbedder.fetch_embedding", mock.AsyncMock(return_value=embedding_response), ) def test_document_embedding(): doc = { "orgId": "orgtest" } doc = embed(document=doc, embedding_endpoint=embedding_endpoint) assert doc["subdocuments"] assert len(doc["title_embedding"]) == embedding_dim assert len(doc["subdocuments"]) == len(doc["paragraphs"]) assert len(doc["subdocuments"][0][embedding_name]) == embedding_dim
方案2:零依赖手动实现异步模拟对象
如果不想额外安装第三方包,可以直接定义一个异步函数作为模拟对象,只要该函数返回预期的结果即可满足基础测试要求:
注意:本方案仅适合只需要模拟返回值的场景,如果需要验证模拟方法的调用次数、调用参数等信息,优先选择方案1,backport 版本的 AsyncMock 完全兼容 Python 3.8+ 原生 AsyncMock 的所有 API。
修改后的测试代码如下:
from unittest import mock # 手动实现异步模拟方法 async def mock_fetch_embedding(*args, **kwargs): return embedding_response @mock.patch( "project.celerytasks.embedder.BulkEmbedder.fetch_embedding", mock_fetch_embedding, ) def test_document_embedding(): doc = { "orgId": "orgtest" } doc = embed(document=doc, embedding_endpoint=embedding_endpoint) assert doc["subdocuments"] assert len(doc["title_embedding"]) == embedding_dim assert len(doc["subdocuments"]) == len(doc["paragraphs"]) assert len(doc["subdocuments"][0][embedding_name]) == embedding_dim
内容的提问来源于stack exchange,提问作者wandermonk
相关产品推荐
相关产品推荐

