javamockitoresthighlevelclient

Java Mocking a private final field or response form RestHighLevelClient


I am trying to write a testcase for the below method and I need to mock the response obtained from the elastic search db.

@Inject
ESEntity mockElasticSearchEntity;
private final RestHighLevelClient restHighLevelClient = OpenSearchRestHighLevelClient.getRestHighLevelClient();

public String getAllMoviesListResult(String index){
    SourceBuilder sourceBuilder = entity.createElasticSearchQueryForGetAllMovieList();
    SearchRequest searchRequest = new SearchRequest(index);
    searchRequest.source(sourceBuilder);

    SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOption.DEFAULT);
    return searchResponse.getHits().get(0);
}

I have written the below test case: Instead of getting the mock response, the code flows to RestHighLevelClient class and returns NullPointException.

@InjectMock
ESEntity mockElasticSearchEntity;

@Test
public void testgetAllMoviesListResult(){
    ESEntity elasticSearchEntity = new ESearchEntity();
    SearchSourceBuilder sourceBuilder = elasticSearchEntity.createElasticSearchQueryForGetAllMovieList();
    when(mockElasticSearchEntity.createElasticSearchQueryForGetAllMovieList()).thenReturn(sourceBuilder);
    
    String esReponse ="";
    JsonXContentParser xContentParser = new JsonXContentParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, new JsonFactory().createParser(esResponse));
    SearchResponse searchResponse = SearchResponse.fromXContent(xContentParser);

    RestHighLevelClient mockRestHighLevelClient = mock(RestHighLevelClient.class);
    when(mockRestHighLevelClient.search(any(),any())).thenReturn(searchResponse);
    
    String actualResponse = new EntityService().getAllMoviesListResult("someIndex");
    
}

I searched for similar issues but that required the use of PowerMock, which is not supported by the framework which I am currently using.

Update

public class OpenSearchRestHighLevelClient {

    private static RestHighLevelClient restHighLevelClient = null;
    
    public static RestHighLevelClient getRestHighLevelClient() {     
        //singleton implementation on receiving the RestHighLevelClient.
        if(restHighLevelClient==null) {
            restHighLevelClient = createRestHighLevelClient();
        }
        return restHighLevelClient;
    }
    
    public static RestHighLevelClient createRestHighLevelClient(){
        //logic to create RestHighLevelClient
    }
}

Solution

  • There's a workaround I can think of, you can mock the static method of object creation of RestHighLevelClient using mock static(checkout) https://mvnrepository.com/artifact/org.mockito/mockito-inline

    I am using Gradle testImplementation 'org.mockito:mockito-inline:3.4.6' This worked for me, let me know

        @Test
        public void testgetAllMoviesListResult() {
            ESEntity elasticSearchEntity = new ESearchEntity();
            SearchSourceBuilder sourceBuilder = elasticSearchEntity.createElasticSearchQueryForGetAllMovieList();
            when(mockElasticSearchEntity.createElasticSearchQueryForGetAllMovieList()).thenReturn(sourceBuilder);
    
            String esReponse = "";
            JsonXContentParser xContentParser = new JsonXContentParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, new JsonFactory().createParser(esResponse));
            SearchResponse searchResponse = SearchResponse.fromXContent(xContentParser);
    
            RestHighLevelClient mockRestHighLevelClient = mock(RestHighLevelClient.class);
            when(mockRestHighLevelClient.search(any(), any())).thenReturn(searchResponse);
            
            try (MockedStatic<OpenSearchRestHighLevelClient> openSearchRestHighLevelClient = mockStatic(OpenSearchRestHighLevelClient.class)) {
                openSearchRestHighLevelClient.when(OpenSearchRestHighLevelClient::getRestHighLevelClient).thenReturn(mockRestHighLevelClient);
                String actualResponse = new EntityService().getAllMoviesListResult("someIndex");
                assertEquals(expectedResponse, actualResponse);
            }
    
        }