I am new to Mockito framework, and I am working on writing tests for the class containing ElasticClient. Below is my actual method:
@Service
@Slf4j
public class CreateIndex {
private final RestHighLevelClient elasticClient;
@Autowired
public IndexService(final RestHighLevelClient elasticClient) throws IOException {
this.elasticClient = elasticClient;
}
public boolean createIndex(String id, String index) {
try {
IndexRequest request = new IndexRequest(index);
request.id(id);
elasticClient.index(request, RequestOptions.DEFAULT);
return true;
} catch (IOException e) {
log.warn(e.getMessage());
}
return false;
}
My test code looks like this:
public class TestCreateIndex {
CreateIndex createIndex;
@Mock
RestHighLevelClient elasticClient;
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Before
public void before() throws IOException {
createIndex = new CreateIndex(elasticClient);
}
@Test
public void TestCreateIndex() throws IOException {
IndexRequest request = new IndexRequest("1");
request.id("1");
Mockito.when(elasticClient.index(request,(RequestOptions.DEFAULT))).thenReturn(indexResponse);
}
}
For the line Mockito.when(elasticClient.index(request,RequestOptions.DEFAULT )).thenReturn(indexResponse);
(RequestOptions is some Class), I am getting below error:
java.lang.NullPointerException: Cannot invoke "org.elasticsearch.client.RestClient.performRequest(org.elasticsearch.client.Request)" because "this.client" is null
at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1514)
at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1484)
at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1454)
at org.elasticsearch.client.RestHighLevelClient.index(RestHighLevelClient.java:871)
Not sure, how to mock elasticClient properly. Please help.
The problem is that the method you are trying to stub is final:
public final IndexResponse index(IndexRequest indexRequest,
RequestOptions options) throws IOException
Mockito does not support mocking final methods out of the box,
instead it calls the real method, which causes NPE, since private final RestClient client;
is not initialized.
Fortunately, stubbing final methods can be easily added as a configuration option. See Mock Final Classes and Methods with Mockito
Before Mockito can be used for mocking final classes and methods, it needs to be configured.
We need to add a text file to the project's src/test/resources/mockito-extensions directory named org.mockito.plugins.MockMaker and add a single line of text:
mock-maker-inline
Mockito checks the extensions directory for configuration files when it is loaded. This file enables the mocking of final methods and classes.
Alternatively, since mockito 2.7.6, you can use mockito-inline
artifact (instead of mockito-core
) that enables inline mock making