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