javaunit-testingelasticsearchintegration-testingelasticsearch-jest

Java Elasticsearch database testing


i'm currently using ES 5 and Jest in a project i'm working in, and i was assigned to to integration and unit testing on the classes that interact with the DB.

lets asume i have a method like this:

 @Override
public Aptitude save(Aptitude aptitude) {
    Index index = new Index.Builder(aptitude).index(aptitudeIndexName).type(aptitudeTypeName).refresh(true).build();
    try {
        client.execute(index);
        return aptitude;
    } catch (IOException e) {
        logger.error("The aptitude couldn't be saved in the data base " + e.getMessage());
        throw new RuntimeException(e);
    }
}

or one like this:

@Override
public List<Aptitude> findAll() {
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.query(QueryBuilders.matchAllQuery());
    searchSourceBuilder.sort("id", SortOrder.ASC);

    Search search = new Search.Builder(searchSourceBuilder.toString()).addIndex(aptitudeIndexName).build();

    try {
        SearchResult result = client.execute(search);

        if (!result.isSucceeded()) {
            return null;
        }

        List<Hit<Aptitude, Void>> aptitudes = result.getHits(Aptitude.class);
        return aptitudes.stream().map(this::getAptitude).collect(Collectors.toList());
    } catch (IOException e) {
        logger.error("The search couldn't be executed" + e.getMessage());
        throw new RuntimeException(e);
    }
}

and my task is to write some test (unit and integration) to make sure all my classes are working correctly and to have better test coverage, i searched a bit online for ES testing but can quite grasp how im supposed to make the tests.

i made some tests that looked like this:

@Test
public void aptitudeSaveDelete() {
    Aptitude aptitude = new Aptitude();
    aptitude.setId(1993L);
    aptitude.setEn("ENaptitudeEN");
    aptitude.setEs("ESaptitudeES");
    Aptitude aptitudeSaved = elasticsearchAptitudeRepository.save(aptitude);

    assertEquals(aptitude.getEs(), aptitudeSaved.getEs());
    assertEquals(aptitude.getEn(), aptitudeSaved.getEn());
    assertEquals(aptitude.getId(), aptitudeSaved.getId());

    Aptitude aptitudeFoundById = elasticsearchAptitudeRepository.findById(String.valueOf(aptitude.getId()));

    assertEquals(aptitude.getId(), aptitudeFoundById.getId());
    assertEquals(aptitude.getEn(), aptitudeFoundById.getEn());
    assertEquals(aptitude.getEs(), aptitudeFoundById.getEs());

    boolean wasDeleted;
    wasDeleted = elasticsearchAptitudeRepository.deleteAptitudeById(String.valueOf(aptitude.getId()));
    assertEquals(true, wasDeleted);
}

but my coworkers told me that this kind of test compromised the DB and that in case something went wrong with them then the DB would had to be repaired manually.

so that is why im at a loss here, any kind of help is apreciated


Solution

  • First you should not test framework. You should test your code. E.g.: Is my mapping right?

    Second: Every integration test should prepare DB to be in known state even if previous test failed.

    I usually use DBunit for data population and evaluation*.

    Citation from their Best Practices

    Note *: I did not used elastic search yet.