You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
from unittest import TestCase
from elasticmock import elasticmock
from elasticsearch import Elasticsearch
def some_function_that_uses_elasticsearch():
client = Elasticsearch(hosts=[{"host": "localhost", "port": 9200}])
id = client.index("test-index", {"a": "b"})
print(id)
return True
class TestClass(TestCase):
@elasticmock
def test_should_return_something_from_elasticsearch(self):
self.assertIsNotNone(some_function_that_uses_elasticsearch())
If I run the test without a local instance of Elasticsearch running I get the following error.
elasticsearch.exceptions.ConnectionError: ConnectionError(<urllib3.connection.HTTPConnection object at 0x7ff720769370>:
Failed to establish a new connection: [Errno 61] Connection refused) caused by:
NewConnectionError(<urllib3.connection.HTTPConnection object at 0x7ff720769370>:
Failed to establish a new connection:
[Errno 61] Connection refused)
If I step through in the debugger I see that the client is an ElasticSearch object and not a FakeElasticSearch object. Apparently the @elasticmock decorator has no effect.
I have the same problem with the pytest framework.
from elasticmock import elasticmock
from elasticsearch import Elasticsearch
@elasticmock
def test_mocked_elasticsearch_client():
client = Elasticsearch(hosts=[{"host": "localhost", "port": 9200}])
id = client.index("test-index", {"a": "b"})
print(id)
The "Code Example" with FooService on the project homepage does work. But I can't figure out what is wrong with the variants I have here.
This is elasticmock 1.8.1 and elasticsearch 7.13.3 on OS X with Python 3.9.15.
The text was updated successfully, but these errors were encountered:
I believe this is due to how @elasticmock is patching ES and how you're importing the client class. @elasticmock uses unittest.mock.patch to essentially do setattr(elasticsearch, 'Elasticsearch', <mock_class>), so that any future getattr(elasticsearch, 'Elasticsearch') will return the mocked class. This happens at test function call time.
Before this happens, you already imported the (original) ElasticSearch class from the (unpatched) elasticsearch module into your namespace, and setattr does not work in-place so your namespace retains the original class reference, which your test function then uses.
Workarounds will involve ensuring you do your getattr on the elasticsearch module afterelasticmock has done setattr a.k.a. inside your test function:
a) Move the elasticsearch import inside the test function.
b) Change your top-level import to be import elasticsearch, then access the Elasticsearch class inside the test function with elasticsearch.Elasticsearch (this is what I did for my use-case).
I don't know what a good prevention measure would be for this. I don't think elasticmock can see the Elasticsearch class reference in your local namespace, so it can't patch it for you.
I have written the following unit test.
If I run the test without a local instance of Elasticsearch running I get the following error.
If I step through in the debugger I see that the client is an
ElasticSearch
object and not aFakeElasticSearch
object. Apparently the@elasticmock
decorator has no effect.I have the same problem with the
pytest
framework.The "Code Example" with
FooService
on the project homepage does work. But I can't figure out what is wrong with the variants I have here.This is elasticmock 1.8.1 and elasticsearch 7.13.3 on OS X with Python 3.9.15.
The text was updated successfully, but these errors were encountered: