Python Mock类导入错误

时间:2018-01-18 17:05:18

标签: python elasticsearch mocking

我正在尝试在我的Python测试用例中模拟 elasticsearch.Elasticsearch.indices.exists 函数,但是我收到以下导入错误。但是,模拟 elasticsearch.Elasticsearch 工作正常。

@ddt
class TestElasticSearchConnector(unittest.TestCase):

    @patch('elasticsearch.Elasticsearch.indices.exists')
    @patch('connectors.elastic_search_connector.ElasticSearchConnector._get_local_conn')
    def test_check_index(self, mock_es, _get_local_conn):
        mock_es = Mock()
        mock_es._index_exists = False
        mock_es.indices.exists.return_value = True
        mock_es.create.return_value = {'result': 'created'}

在此处获取模拟导入错误

=============================================== =======================     错误:test_check_index(tests.base.TestESConnector)     -------------------------------------------------- --------------------     Traceback(最近一次调用最后一次):       在_dot_lookup中输入文件“/Users/user/.virtualenvs/my-prjlib/python3.6/site-packages/mock/mock.py”,第1197行         return getattr(thing,comp)     AttributeError:类型对象'Elasticsearch'没有属性'indices'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/user/.virtualenvs/my-prjlib/python3.6/site-packages/mock/mock.py", line 1297, in patched
    arg = patching.__enter__()
  File "/Users/user/.virtualenvs/my-prjlib/python3.6/site-packages/mock/mock.py", line 1353, in __enter__
    self.target = self.getter()
  File "/Users/user/.virtualenvs/my-prjlib/python3.6/site-packages/mock/mock.py", line 1523, in <lambda>
    getter = lambda: _importer(target)
  File "/Users/user/.virtualenvs/my-prjlib/python3.6/site-packages/mock/mock.py", line 1210, in _importer
    thing = _dot_lookup(thing, comp, import_path)
  File "/Users/user/.virtualenvs/my-prjlib/python3.6/site-packages/mock/mock.py", line 1199, in _dot_lookup
    __import__(import_path)
ModuleNotFoundError: No module named 'elasticsearch.Elasticsearch'

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

FAILED (errors=1)

测试导入

>>  user$ python
Python 3.6.1 (default, May 10 2017, 09:46:05) 
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from elasticsearch import Elasticsearch
>>> 
>>> 

2 个答案:

答案 0 :(得分:0)

这是正确的错误。指定要模拟的属性/方法时,它必须存在于对象(在本例中为类)上。也许您希望该属性存在,但它仅在实例化对象上存在。

In [1]: from elasticsearch import Elasticsearch
In [2]: Elasticsearch.indices
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-2-313eaaedb2f6> in <module>()
----> 1 Elasticsearch.indices

实际上,它存在于实例化的对象上

In [3]: Elasticsearch().indices
Out[3]: <elasticsearch.client.indices.IndicesClient at 0x102db0a90>

答案 1 :(得分:0)

实例化indices对象时,Elasticserch库会生成Elasticsearch()属性。它使用称为IndicesClient的库的类来执行此操作,并且该类具有exists方法。因此,如果模拟IndicesClient类的方法的响应,则测试应该可以进行。

此外,函数的输入参数应与装饰器相反,顺序相反。如果您将indices.exists补丁放在首位,那么在该函数的输入中应该排第二。

from elasticsearch.client import IndicesClient

@mock.patch.object(IndicesClient, 'exists')
@mock.patch('connectors.elastic_search_connector.ElasticSearchConnector._get_local_conn')
def test_check_index(self, mock_get_local_conn, mock_exists):
    mock_exists.return_value = True
    ...