4

How can I control the IndexResponse when using the Elasticsearch async api w/ the HighLevelRestClient v7.5?

Maybe I need to mock the Low Level REST Client and use that mock for my High Level REST Client? 🤔

@Test
void whenIndexResponseHasFailuresDoItShouldReturnFalse() {

  // arrange
  var indexResponse = mock(IndexResponse.class);
  when(indexResponse.getResult()).thenReturn(Result.UPDATED);

  var restHighLevelClient = mock(RestHighLevelClient.class);
  when(restHighLevelClient.indexAsync())
      //do something here??

  var indexReqest = new IndexRequest(...);

  //act
  var myHelper = new MyHelper(restHighLevelClient);
  var result = myHelper.doIt(indexReqest)
    .get();

  //assert
  assert(result).isFalse();
}
class MyHelper {

  //injected RestHighLevelClient

  CompletableFuture<Boolean> doIt(Customer customer) {

    var result = new CompletableFuture<Boolean>();
    var indexRequest = new IndexRequest(...);

    restHighLevelClient.indexAsync(indexRequest, RequestOptions.DEFAULT
         , new ActionListener<IndexResponse>() {
      @Override
      public void onResponse(IndexResponse indexResponse) {  //want to control indexResponse
        if (indexResponse.getResult() == Result.UPDATED) {
          result.complete(false);
        } else {
          result.complete(true);
        }
      }

      @Override
      public void onFailure(Exception e) {
        ...
      }
    });

    return result;
  }
}

Update Sample project using Oleg's answer

4
  • Refactor your code. You can't unit test if RestHighLevelClient is created in doIt Commented Feb 25, 2020 at 22:57
  • It’s not, I’ll update my question, it’s injected, good point, thanks 😊 @Oleg Commented Feb 25, 2020 at 23:16
  • Feel free to ignore this comment and not answer, it doesn't really matter anyway, I'm just curious; why did you accept my answer but didn't upvote it? Commented Feb 27, 2020 at 1:51
  • Hi @Oleg - I'm experimenting/researching, I've usually accepted and upvoted. Interesting read. Before I upvoted, in this case, I wanted to research "should I accept and upvote or just accept? what's the 'right' way?" Commented Feb 27, 2020 at 12:52

1 Answer 1

2

Mock RestHighLevelClient then inside indexAsync mock IndexResponse and pass it to the ActionListener.

RestHighLevelClient restHighLevelClient = mock(RestHighLevelClient.class);
when(restHighLevelClient.indexAsync(any(), any(), any())).then(a -> {
    ActionListener<IndexResponse> listener = a.getArgument(2);
    IndexResponse response = mock(IndexResponse.class);
    when(response.getResult()).then(b -> {
        return Result.UPDATED;
    });
    listener.onResponse(response);
    return null;
});
MyHelper myHelper = new MyHelper(restHighLevelClient);
Boolean result = myHelper.doIt(null).get();
assertFalse(result);

Also, configure Mockito to support mocking final methods otherwise a NPE will be thrown when mocking indexAsync.

Option 1

Instead of using the mockito-core artifact, include the mockito-inline artifact in your project

Option 2

Create a file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker with mock-maker-inline as the content

Sign up to request clarification or add additional context in comments.

4 Comments

restHighLevelClient.indexAsync() is void method. How do you any return ? for Mockito.when()
I don't understand. What return?
Something should "return" in Mockito.when(). Since indexAsync() is void, it doesn't "return" anything. I just asked how this will happen.
@MuratKara It's not a problem. stackoverflow.com/a/29556171/1398418

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.