java - 如何使用 Elasticsearch async api 控制响应

标签 java unit-testing elasticsearch mockito

使用 Elasticsearch 时如何控制 IndexResponse async api带有 HighLevelRestClient v7.5?

也许我需要模拟 Low Level REST Client并为我的 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;
  }
}

更新 Sample project使用 Oleg 的回答

最佳答案

模拟 RestHighLevelClient 然后在 indexAsync 模拟 IndexResponse 并将其传递给 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);

此外,配置 Mockito 以支持模拟 final 方法,否则 NPE将在模拟 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

关于java - 如何使用 Elasticsearch async api 控制响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60403460/

相关文章:

unit-testing - 起订量和访问调用的参数

elasticsearch - 根据顶级过滤器聚合创建不同的子聚合

c# - J2EE 和 C#/.Net 在开发 Web 服务时的主要​​区别

android - 如何在 Android 单元测试中访问资源?

ruby-on-rails - 辅助规范上的 output_buffer 为空

amazon-web-services - 在Elasticsearch上安装repository-se插件

elasticsearch - 在Elasticsearch中删除文档

java - 每次运行应用程序时都会创建一个新数据库吗?

java - 通过 OpenCV 在 Android 中使用 native 函数

java - Gradle 任务未按要求运行(编译前)