我正在尝试在我的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
>>>
>>>
答案 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
...