ElasticSearch Unit Testing - best practices and approach

Hi All,

I am currently facing a issue when trying to unit test my elasticsearch search method.
Here is my Service:

@Service
@Slf4j
public class FullService {

private final RestHighLevelClient client;
private final ObjectMapper objectMapper;
private final SearchRequest searchRequest = new SearchRequest();
private final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
private       SearchResponse searchResponse = new SearchResponse();
private final ESBuilder esBuilder = new ESBuilder();


FullService(RestHighLevelClient client, ObjectMapper objectMapper) {
    this.client = client;
    this.objectMapper = objectMapper;
    searchRequest.indices(INDEX);

  }

public Results findAll() throws IOException {
    searchSourceBuilder.query(QueryBuilders.matchAllQuery());
    searchRequest.source(searchSourceBuilder);
    searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

    return getAllSearchResult(searchResponse);

  }

public Results findByRequestSearch(UserSearchRequest request) throws IOException {
    searchSourceBuilder.query(esBuilder.buildQuery(request));
    searchRequest.source(searchSourceBuilder);
    searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
    return getAllSearchResult(searchResponse);
  } 
}

The Client is built outside the class in an ESConfig file:

@Configuration
class ESConfig {


@Value("${elasticsearch.host}")
private String host;

@Value("${elasticsearch.port}")
private int port;

@Value("${elasticsearch.username}")
private String userName;

@Value("${elasticsearch.password}")
private String password;

@Bean(destroyMethod = "close")
public RestHighLevelClient restClient() {

    final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY,
            new UsernamePasswordCredentials(userName, password));

    RestClientBuilder builder = RestClient.builder(new HttpHost(host, port))
            .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));


    return new RestHighLevelClient(builder);

}
}

So I'm trying to test the findByRequestSearch() method. but keep getting a null pointer exception

Here is my Test Class:

@RunWith(PowerMockRunner.class)
public class powerMockTest {

@Mock
RestHighLevelClient highLevelClient;


ObjectMapper objectMapper;
SearchSourceBuilder searchSourceBuilder;
ESBuilder esBuilder;


private FullService fullService;

@Mock
SearchResponse searchResponse;

@Before
public void setUp() throws Exception {
    objectMapper = new ObjectMapper();
    fullService = new FullService(highLevelClient,objectMapper);
    searchSourceBuilder = new SearchSourceBuilder();
    esBuilder = new ESBuilder();

}

@Test
public void testFindByRequest() throws IOException {

    //Build Request
    UserSearchRequest request = new UserSearchRequest();
    SearchCriteria searchCriteria = new SearchCriteria();
    List<SearchTerms> searchTermsList = new ArrayList<>();
    SearchTerms searchTerms = new SearchTerms();

    searchTerms.setAttribute("compoundName");
    searchTerms.setValue("Odell");
    searchTermsList.add(searchTerms);
    searchCriteria.setSearchTerms(searchTermsList);
    request.setSearchCriteria(searchCriteria);

    //ES Search Request
    SearchRequest searchRequest = new SearchRequest();
    searchSourceBuilder.query(esBuilder.buildQuery(request));
    searchRequest.source(searchSourceBuilder);

    Mockito.when(highLevelClient.search(searchRequest, RequestOptions.DEFAULT)).thenReturn(searchResponse);

    Mockito.verify(highLevelClient,Mockito.times(1)).search(Mockito.any(SearchRequest.class),RequestOptions.DEFAULT);
    Mockito.verifyNoMoreInteractions(highLevelClient);

}}

Any Help with this would be appreciated but also any guidance on best practices around testing methods that call ES components.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.