How do I Unit test/mock ElasticSearch How do I Unit test/mock ElasticSearch elasticsearch elasticsearch

How do I Unit test/mock ElasticSearch


since elastic search is java and your code is too (or compatible) the best approach would be figure out a way to boot elastic search "embeddable" - just start their server up in your @Before method and shut it down / clear it in @After.

luckily for you, it seems like someone already had the exact same idea - https://orrsella.com/2014/10/28/embedded-elasticsearch-server-for-scala-integration-tests/


In my own code, I recently wrote up a small Embeddable elastic search for testing. It stores things on Disk and then can delete the files after use. I use this to run my various elasticsearch unit test.

It make a single node elasticsearch cluster. This node supports the full elasticsearch API.

 /** * A simple embeddable Elasticsearch server. This is great for integration testing and also * stand alone tests. * * Starts up a single ElasticSearch node and client. */public class EmbeddedElasticsearchServer{  public EmbeddedElasticsearchServer(String storagePath) {    storagePath_ = storagePath;    ImmutableSettings.Builder elasticsearchSettings = ImmutableSettings.settingsBuilder()      .put("http.enabled", "false")      .put("path.data", storagePath_);    node_ = new NodeBuilder()      .local(true)      .settings(elasticsearchSettings.build())      .node();    client_ = node_.client();  }  public Client getClient() {    return client_;  }  public void shutdown()  {    node_.close();  }  public void deleteStorage() throws IOException  {    File storage = new File(storagePath_);    if(storage.exists())    {      FileUtils.deleteDirectory(storage);    }  }  private Client client_;  private Node node_;  private String storagePath_;}

To use it, just call getClient and then you can use the Elasticsearch Java API just fine.


For our ElasticSearch tests we use an always-on instance of ElasticSearch on our Jenkins build server that each test uses. For local tests, you have to fire up your local ElasticSearch. We use the rest interface, not the java api.

In order to make the unit tests parallelizable, we use an global, synchronized name pool (for index names). Each test can configure an index definition json, and if it is ok to run on an dirty (= already filled) index. A small test superclass (scalatest) will aquire an index name from the pool. If a clean index is required, an (maybe) existing one is deleted and the new one created. If the test accepts an dirty index, it is checked if the index definition is the same as the configured one. If not, the index is also re-created.

Depending on your test cases, this enables you to go with a few indexes that will be recreated once in a while, and being reused often by tests, speeding up test execution.