【问题标题】:Getting NPE error when trying to mock ElasticClient in Mockito [duplicate]尝试在 Mockito 中模拟 ElasticClient 时出现 NPE 错误 [重复]
【发布时间】:2021-04-01 14:34:16
【问题描述】:

我是 Mockito 框架的新手,我正在为包含 ElasticClient 的类编写测试。下面是我的实际方法:

@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;
    }

我的测试代码如下所示:

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);

    }
}

对于Mockito.when(elasticClient.index(request,RequestOptions.DEFAULT )).thenReturn(indexResponse);(RequestOptions 是某个类)这一行,我遇到以下错误:

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)

不确定,如何正确模拟 elasticClient。请帮忙。

【问题讨论】:

  • 请向我们展示整个堆栈跟踪
  • @Lesiak 我已添加更新的堆栈跟踪,请参阅
  • 任何人请帮我解决 NPE 错误! :(
  • 问题是 mockito 特有的,而不是典型的 NPE,因此重新投票

标签: java unit-testing elasticsearch junit mockito


【解决方案1】:

问题是您尝试存根的方法是最终的:

public final IndexResponse index(IndexRequest indexRequest, 
                                 RequestOptions options) throws IOException

Mockito 不支持开箱即用地模拟最终方法, 相反,它调用了导致 NPE 的真实方法,因为 private final RestClient client; 未初始化。

幸运的是,可以轻松地将存根 final 方法添加为配置选项。 见Mock Final Classes and Methods with Mockito

在 Mockito 可用于模拟 final 类和方法之前,需要对其进行配置。

我们需要在项目的 src/test/resources/mockito-extensions 目录中添加一个名为 org.mockito.plugins.MockMaker 的文本文件并添加一行文本:

mock-maker-inline

Mockito 在加载时会检查扩展目录中的配置文件。该文件可以模拟 final 方法和类。

或者,从 mockito 2.7.6 开始,您可以使用 mockito-inline artifact(而不是 mockito-core)来启用内联模拟制作

【讨论】:

  • 我检查了我的 IndexRequest.class 和 IndexResponse.class,它们都不是最终类。但是,是的,我确实将 RestClient 作为私人决赛 private final RestClient client;
  • 我的代码中使用的 mockito 版本是 2.23.4。所以 mockito-inline 不受支持,而且由于 java 和 mockito 之间的版本问题,mock-maker-inline 的事情也导致了很多错误。
  • 23 大于 7 不是吗?另外,我说方法是最终的,而不是参数。 RestClient 是 RestHighLevelClient 中的一个字段,而不是您的代码中的一个字段。请花点时间重新阅读我的答案。
猜你喜欢
  • 1970-01-01
  • 2023-01-18
  • 1970-01-01
  • 2015-02-12
  • 2016-09-14
  • 2016-11-05
  • 1970-01-01
  • 2022-12-29
  • 2017-11-07
相关资源
最近更新 更多