Python Elasticsearch Mock for test purposes
pip install ElasticMock
To use ElasticMock, decorate your test method with @elasticmock decorator:
from unittest import TestCase
from elasticmock import elasticmock
class TestClass(TestCase):
@elasticmock
def test_should_return_something_from_elasticsearch(self):
self.assertIsNotNone(some_function_that_uses_elasticsearch())
You can also force the behaviour of the ElasticSearch instance by importing the elasticmock.behaviour
module:
from unittest import TestCase
from elasticmock import behaviour
class TestClass(TestCase):
...
def test_should_return_internal_server_error_when_simulate_server_error_is_true(self):
behaviour.server_failure.enable()
...
behaviour.server_failure.disable()
You can also disable all behaviours by calling behaviour.disable_all()
(Consider put this in your def tearDown(self)
method)
server_failure
: Will make all calls to ElasticSearch returns the following error message:{ 'status_code': 500, 'error': 'Internal Server Error' }
Let's say you have a prod code snippet like this one:
import elasticsearch
class FooService:
def __init__(self):
self.es = elasticsearch.Elasticsearch(hosts=[{'host': 'localhost', 'port': 9200}])
def create(self, index, body):
es_object = self.es.index(index, body)
return es_object.get('_id')
def read(self, index, id):
es_object = self.es.get(index, id)
return es_object.get('_source')
Than you should be able to test this class by mocking ElasticSearch using the following test class:
from unittest import TestCase
from elasticmock import elasticmock
from foo.bar import FooService
class FooServiceTest(TestCase):
@elasticmock
def should_create_and_read_object(self):
# Variables used to test
index = 'test-index'
expected_document = {
'foo': 'bar'
}
# Instantiate service
service = FooService()
# Index document on ElasticSearch
id = service.create(index, expected_document)
self.assertIsNotNone(id)
# Retrive dpcument from ElasticSearch
document = service.read(index, id)
self.assertEquals(expected_document, document)
- The mocked search method returns all available documents indexed on the index with the requested document type.
- The mocked suggest method returns the exactly suggestions dictionary passed as body serialized in Elasticsearch.suggest response. Atention: If the term is an int, the suggestion will be
python term + 1
. If not, the suggestion will be formatted aspython {0}_suggestion.format(term)
. Example:- Suggestion Body:
suggestion_body = { 'suggestion-string': { 'text': 'test_text', 'term': { 'field': 'string' } }, 'suggestion-id': { 'text': 1234567, 'term': { 'field': 'id' } } }
- Suggestion Response:
{ 'suggestion-string': [ { 'text': 'test_text', 'length': 1, 'options': [ { 'text': 'test_text_suggestion', 'freq': 1, 'score': 1.0 } ], 'offset': 0 } ], 'suggestion-id': [ { 'text': 1234567, 'length': 1, 'options': [ { 'text': 1234568, 'freq': 1, 'score': 1.0 } ], 'offset': 0 } ], }
python setup.py test
- Add multi_match (Thanks @carlosgalvez-tiendeo)
- Add mget (Thanks @carlosgalvez-tiendeo)
- Add create, update, and delete to bulk API (Thanks @fenimore)
- Add Should to bool Query (Thanks @fenimore)
- Update Search API return result (Thanks @fenimore)
- Add shards skipped to search and count (Thanks @philtweir)
- Allow 'match_all' queries in FakeSearch (Thanks @jankislinger)
- Query using nested attributes (Thanks @jankislinger)
- New features: range, size, aggregations (Thanks @jankislinger)
- Adding "should" and "minimum_should_match" to QueryType (Thanks @lunarie16)
- Add must to query type (Thanks @cuent)
- Add match all query type (Thanks @cuent)
- Fix Twine README.md
- Implements several basic search types (Thanks @KyKoPho)
- Allow ignoring of missing documents (404) for get and delete (Thanks @joosterman)
- Fix tests for es > 7 (Thanks @chesstrian)
- FakeElasticSearch: Mocked indices property
- FakeIndicesClient: Mocked create, exists, refresh and delete methods
- FakeElasticSearch: Mocked cluster property
- FakeClusterClient: Mocked health method
- Fix es.index regression issue
- Add 'Force Server Failure' feature as requested
- Reformat code to be compliant with PEP8
- Add support to Python 3.8
- Adding fix for updating existing doc using index (Thanks @adityaghosh)
- Added bulk method (Thanks @charl-van-niekerk)
- Add default value to doc_type in index method as it is by default set to '_doc' (Thanks @mohantyashish109)
- Add support for Python 3.7 (Thanks @asherf)
- Fix installation issue (Thanks @tdhopper)
- Fix 1.3.4 release (Thanks @infinite-Joy)
- Added aggregations to response if requested (Thanks @snakeye)
- Implementing new methods for scrolling (Thanks @tcatrain)
- Search: doc_type can be a list (Thanks @garncarz)
- Exclude tests package (Thanks @jmlw)
- Make the FakeElasticsearch init signature match the one from Elasticsearch (Thanks @xrmx)
- Improve search and count (Thanks @frivoire)
- elasticmock: Python 3 fixes (Thanks @barseghyanartur)
- test: Add information on testing (Thanks @barseghyanartur)
- README.md: Fixed typo (Thanks @bowlofstew)
- elasticmock: Allow the same arguments to the mock that elasticsearch.Elasticsearch allows (Thanks @mattbreeden)
- FakeElasticSearch: Mocked count method (Thanks @TheoResources)
- FakeElasticSearch: Mocked suggest method
- elasticmock: Changing the cleanup older FakeElasticSearch's instances order
- FakeElasticSearch.index: Changing the method signature to correctly overrides the Elasticsearch.index method
- FakeElasticSearch: Mocked delete method
- setup.py: Fixed GitHub link
- elasticmock: Created @elasticmock decorator
- FakeElasticSearch: Mocked exists, get, get_source, index, info, search and ping method