如何使用Elasticsearch异步API控制响应

4
当使用Elasticsearch async apiHighLevelRestClient v7.5时,我该如何控制IndexResponse?也许我需要模拟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;
  }
}

更新 示例项目 使用Oleg的答案


重构你的代码。如果 RestHighLevelClient 是在 doIt 中创建的,那么你无法进行单元测试。 - Oleg
不是这样的,我会更新我的问题,它被注入了,好观点,谢谢 @Oleg - spottedmahn
请随意忽略这条评论,不用回答,因为这并不重要。我只是好奇:为什么你接受了我的答案,却没有点赞呢? - Oleg
嗨@Oleg - 我正在进行实验/研究,通常我会接受并点赞。有趣的阅读。在我点赞之前,在这种情况下,我想研究“我应该接受并点赞还是只接受?什么是‘正确’的方式?” - spottedmahn
1个回答

2
模拟 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方法,否则在模拟indexAsync时将抛出NPE选项1

不要使用mockito-core构件,而是在项目中包含mockito-inline构件

选项2

创建一个文件src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker,并将mock-maker-inline作为其内容


restHighLevelClient.indexAsync() 是一个无返回值的方法。在 Mockito.when() 中如何返回任何值? - Murat Kara
我不明白。返回什么? - Oleg
在Mockito.when()中应该有一些东西“返回”。由于indexAsync()是void,它不会“返回”任何东西。我只是想知道这将如何发生。 - Murat Kara
@MuratKara 这不是问题。https://stackoverflow.com/a/29556171/1398418 - Oleg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接