0

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
    }
}
User27854
  • 824
  • 1
  • 16
  • 40
  • `RestHighLevelClient` object is being created inside the class scope it is not being injected into the class or method, you can't mock them using mockito – HariHaravelan Mar 31 '22 at 04:13
  • @HariHaravelan, how can I modify the code to make the code testable? – User27854 Mar 31 '22 at 04:38
  • 1
    I think you're using Spring, create the `restHighLevelClient` as `@Bean` since the implementation looks to be the same for all, move to @Configuration, and inject `restHighLevelClient` to the class you're testing then you should be able to mock – HariHaravelan Mar 31 '22 at 04:46
  • @HariHaravelan, I am using microProfile framework. I am stuck while changing the code as OpenSearchRestHighLevelClient.getRestHighLevelClient(); is a singleton implementation. Not sure how to modify the code to allow injection. At the same time maintaining singleton. I have updated the code kindly have a look at it. – User27854 Mar 31 '22 at 05:18

1 Answers1

0

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);
        }

    }
HariHaravelan
  • 1,041
  • 1
  • 10
  • 19