Testing Mapping with Embedded Elasticsearch Server

Running instance of Elasticsearch cluster server won’t available for unit test. On the other hand, unit test shouldn’t depend on the external running instance. If you want to test the real Elasticsearch behavior in unit test, you can use embedded Elasticsearch server instance. Embedded Elasticsearch server is a small instance of Elasticsearch cluster and it works exactly as Elasticsearch cluster as a whole.
You need following dependency in POM file to run Elasticsearch as embedded in your application for unit test.

	<dependency>
	    <groupId>org.elasticsearch</groupId>
	    <artifactId>elasticsearch</artifactId>
	    <version>5.2.1</version>
	</dependency>
        <dependency>
	    <groupId>org.elasticsearch.client</groupId>
	    <artifactId>transport</artifactId>
	    <version>5.2.1</version>
	</dependency>
	<dependency>
	    <groupId>com.google.guava</groupId>
	    <artifactId>guava</artifactId>
	    <version>21.0</version>
	</dependency>

Following code tests that whether the mapping has been created in Elasticsearch or not. We can do using Mockito. However, I don’t think Mockito will give us full confidence on our code. I am using embedded Elasticsearch to make sure I can create index and mapping without any issue. If you want to see the mapping, Please click here for my mapping tutorial.

package com.vsubedi.elasticsearch;

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;

import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.node.Node;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.io.Files;

/**
 *
 * @author vsubedi
 *
 */
public class PrepareIndexTest {

	private static final Logger logger = LoggerFactory.getLogger(PrepareIndexTest.class);

	private static Node server;
	private static Client client;
	private static File tempDir;
	private static String index = "test";
	private static String docType = "movies";

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		logger.info("======= START INTEGRATION TEST ========");

		// spinning up the elasticsearch server for junit
		tempDir = Files.createTempDir();
		logger.info(tempDir.getAbsolutePath());
		Settings settings = Settings.builder().put("path.home", tempDir.getAbsolutePath())
				.put("transport.type", "local")
				.put("http.enabled", false)
				.build();
		server = new Node(settings);
		final String clusterName = server.settings().get("cluster.name");

		logger.info("starting server with cluster-name: [{}]", clusterName);
		server.start();

		client = server.client();
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		DeleteIndexResponse deleteIndexResponse = client.admin().indices()
				.prepareDelete(index).get();
		assertTrue(String.valueOf(deleteIndexResponse.isAcknowledged()).equalsIgnoreCase("true"));
		tempDir.delete();
		client.close();
		server.close();
		logger.info("======= END INTEGRATION TEST ========");
	}

	@Test
	public void testPrepareIndex() throws IOException {
		//creating index
		IndexAndCreateMapping.prepareIndex(client, index, docType);

		//checking if the index has been created or not
		IndicesExistsResponse indexResponse = client.admin().indices().prepareExists(index).get();

		//it should be true
		assertTrue(indexResponse.isExists());
	}

}

Above code is for Elasticsearch version 5.2.1. If you want to run for previous versions like 2.4.0, you need to use NodeBulder to create a embedded Elasticsearch instance as follows:

tempDir = Files.createTempDir();
logger.info(tempDir.getAbsolutePath());
Settings settings = Settings.builder().put("path.home",
tempDir.getAbsolutePath()).build();
server = NodeBuilder.nodeBuilder().settings(settings).build();
final String clusterName = server.settings().get("cluster.name");

logger.info("starting server with cluster-name: [{}]", clusterName);
server.start();

client = server.client();

with following dependency

		<dependency>
			<groupId>org.elasticsearch</groupId>
			<artifactId>elasticsearch</artifactId>
			<version>2.4.1</version>
			<scope>test</scope>
			<type>test-jar</type>
		</dependency>

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s