pytest:如何模拟额外的依赖关系?

2024-09-30 08:16:57 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python项目中,我使用异步Elasticsearch客户端,如下所示:

pip install elasticsearch[async]
from elasticsearch import AsyncElasticsearch

async def es_search(...):
    es_client = AsyncElasticsearch(url, timeout=30)
    es_response = await es_client.search(...)
    return es_response

这正如预期的那样有效

现在,我想编写单元测试,并使用pytestmock模拟这个AsyncElasticsearch客户机行为

我试着写一个基本的test+mock(其中test_appmocker是测试装置):

def test_es_search(test_app, mocker):
    mocker.patch('elasticsearch.AsyncElasticsearch.search', return_value={"data": "foobar"})
    result = es_search()
    assert result == {"data": "foobar"}

运行我的测试时,pytest失败,出现以下错误:

thing = <class 'elasticsearch._async.client.AsyncElasticsearch'>
comp = 'cluster', import_path = 'elasticsearch.AsyncElasticsearch.cluster'

    def _dot_lookup(thing, comp, import_path):
        try:
            return getattr(thing, comp)
        except AttributeError:
>           __import__(import_path)
E           ModuleNotFoundError: No module named 'elasticsearch.AsyncElasticsearch'

在查找已安装的lib路径(elasticsearch[async])之后,我发现这个AsyncElasticsearch类的“真实”路径是“elasticsearch._async.client.AsyncElasticsearch”。因此,我更新了我的模拟以使用以下路径:

def test_es_search(test_app, mocker):
    mocker.patch('elasticsearch._async.client.AsyncElasticsearch.search', return_value={"data": "foobar"})
    result = es_search()
    assert result == {"data": "foobar"}

但同样的事情,pytest失败了:

thing = <class 'elasticsearch._async.client.AsyncElasticsearch'>
comp = 'cluster'
import_path = 'elasticsearch._async.client.AsyncElasticsearch.cluster'

    def _dot_lookup(thing, comp, import_path):
        try:
            return getattr(thing, comp)
        except AttributeError:
>           __import__(import_path)
E           ModuleNotFoundError: No module named 'elasticsearch._async.client.AsyncElasticsearch'

我的问题是:如何模拟这种类,它作为“额外”pip依赖项添加到我的项目中?我应该在mocker.patch()中使用什么样的路径来模拟它?我错过什么了吗


Tags: pathtestimportclientsearchdataasyncreturn

热门问题