尝试在 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
)来启用内联模拟制作
我是 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
)来启用内联模拟制作