Elasticsearch Spring boot integration test

14,291

You can actually do what you need without any additional elasticsearch testing dependencies. The idea is basically to create an embedded node and then use the NodeClient to communicate with it.

For that, I created my own EmbeddedElasticsearchServer class which looks (more or less) like this:

public class EmbeddedElasticsearchServer implements InitializingBean {

    public EmbeddedElasticsearchServer() {

        ImmutableSettings.Builder elasticsearchSettings = ImmutableSettings.settingsBuilder()
                .put("http.enabled", "false")
                .put("path.data", "target/elasticsearch-data");

        node = nodeBuilder()
                .local(true)
                .settings(elasticsearchSettings.build())
                .node();

        client = node.client();


    }

    @Override
    public void afterPropertiesSet() throws Exception {
         // Initialization stuff:
         // - create required indices
         // - define mappings
         // - populate with test data
    }

    public Client getClient() {
         return client;
    }

}

Then, in spring configuration (let's call it integration-test-context.xml) I did this:

<bean id="embeddedElasticsearchServer" 
      class="com.example.EmbeddedElasticsearchServer" />

<bean id="elasticsearchClient"
      class="org.elasticsearch.client.node.NodeClient" 
      factory-bean="embeddedElasticsearchServer" 
      factory-method="getClient" />

Then you can just autowire the client in your test like this:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/integration-test-context.xml")
public abstract class AbstractElasticsearchIntegrationTest {

    @Autowired
    private Client elasticsearchClient;

    // Your rests go here...

}
Share:
14,291

Related videos on Youtube

Jaroslaw.zawila
Author by

Jaroslaw.zawila

Updated on September 15, 2022

Comments

  • Jaroslaw.zawila
    Jaroslaw.zawila over 1 year

    I am looking for the way to add embedded elasticsearch to my spring boot integration test.

    I looked at elastic search integration test but it does not work together with spring boot as both should uses different test runner.

    I have a class test as below unfortunately it does not work with error:

    java.lang.IllegalStateException: No context information for thread: Thread[id=1, name=main, state=RUNNABLE, group=main]. Is this thread running under a class com.carrotsearch.randomizedtesting.RandomizedRunner runner context? Add @RunWith(class com.carrotsearch.randomizedtesting.RandomizedRunner.class) to your test class. Make sure your code accesses random contexts within @BeforeClass and @AfterClass boundary (for example, static test class initializers are not permitted to access random contexts).

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = App.class)
    @WebAppConfiguration
    @IntegrationTest("server.port:0")
    public class TestExample extends ElasticsearchIntegrationTest {
    
        TestRestTemplate testRestTemplate = new TestRestTemplate();
    
        @Value("${local.server.port}")
        int port;
    
        @Test
        public void testOne(){
            ResponseEntity<String> results = testRestTemplate.getForEntity(String.format("http://localhost:%d/client/1", port), String.class);
    
    
    
         System.out.print(results);
        }
    
    }
    

    Does anybody has some ideas how to make them run or what is alternatives ??

  • Jaroslaw.zawila
    Jaroslaw.zawila almost 9 years
    Thank you a lot for your answer. I will try it and accept the answer afterwards. :)
  • Jon
    Jon over 8 years
    This answer helped me out so much. I had spent an entire day trying to make a version of org.elasticsearch.test.InternalTestCluster that I could embedd in a JerseyTest. This made things much easier. One thing to note is make sure you close the node and client somewhere. They need to be cleaned up.
  • Dave Bower
    Dave Bower over 8 years
    In case it helps anyone else this only worked for me when path.data was an absolute path (with ES 1.7.3).
  • Paul Podgorsek
    Paul Podgorsek about 6 years
    According to the ElasticSearch pull requests, the NodeBuilder has been removed and the Node class should be used directly instead.
  • valijon
    valijon over 5 years
    ElasticsearchCrudRepository bean cannot be created if you use node client in integration test.
  • Kalpesh Soni
    Kalpesh Soni about 5 years
    If I had multiple such tests, would it not start the server for each test?
  • Albert Hendriks
    Albert Hendriks over 4 years
    It complains that I need to configure path.home, where then an elasticsearch instance should be.