Skip to content

Python Elasticsearch Mock for test purposes

License

Notifications You must be signed in to change notification settings

g3rg0/elasticmock

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ElasticMock

Python Elasticsearch Mock for test purposes

Build Status Coverage Status PyPI version GitHub license PyPI - Python Version ElasticSearch Version

Libraries.io dependency status for latest release Downloads

Installation

pip install ElasticMock

Usage

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())

Custom Behaviours

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)

Available Behaviours

  • server_failure: Will make all calls to ElasticSearch returns the following error message:
    {
        'status_code': 500,
        'error': 'Internal Server Error'
    }

Code example

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)

Notes:

  • 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 as python {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
            }
        ],
    }

Testing

python setup.py test

Changelog

1.8.0:

1.7.0:

1.6.2:

1.6.1:

  • Fix Twine README.md

1.6.0:

1.5.1:

1.5.0:

1.4.0

1.3.7

1.3.6

1.3.5

1.3.4

1.3.3

1.3.2

1.3.1

  • elasticmock: Allow the same arguments to the mock that elasticsearch.Elasticsearch allows (Thanks @mattbreeden)

1.3.0:

1.2.0:

  • FakeElasticSearch: Mocked suggest method

1.1.1:

  • elasticmock: Changing the cleanup older FakeElasticSearch's instances order
  • FakeElasticSearch.index: Changing the method signature to correctly overrides the Elasticsearch.index method

1.1.0:

  • FakeElasticSearch: Mocked delete method

1.0.1:

  • setup.py: Fixed GitHub link

1.0.0:

  • elasticmock: Created @elasticmock decorator
  • FakeElasticSearch: Mocked exists, get, get_source, index, info, search and ping method

About

Python Elasticsearch Mock for test purposes

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 99.3%
  • Makefile 0.7%