0

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.

Gregory Javis
  • 105
  • 1
  • 4
  • 10

1 Answers1

0

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

Lesiak
  • 22,088
  • 2
  • 41
  • 65
  • I checked my IndexRequest.class and IndexResponse.class, none of them are final classes. But yeah, I do have RestClient as private final `private final RestClient client;` – Gregory Javis Apr 02 '21 at 09:46
  • The mockito version used in my code is 2.23.4. So mockito-inline is not supported and also `mock-maker-inline` thing is causing a lot of errors because of the version issues between java and mockito. – Gregory Javis Apr 02 '21 at 09:49
  • 23 is greater than 7 isn't it? Also, I said the method is final, not it's arguments. RestClient is a field in RestHighLevelClient, not in your code. Please take time to re-read my answer. – Lesiak Apr 02 '21 at 09:54