尝试在 Mockito 中模拟 ElasticClient 时出现 NPE 错误

Getting NPE error when trying to mock ElasticClient in Mockito

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

@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 是一些 Class),我遇到以下错误:

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。请帮忙。

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

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

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

幸运的是,stubbing final 方法可以很容易地添加为配置选项。 参见 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.

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