尝试模拟 Elastic Search 的 RestHighLevelClient 时出现 NullPointerException 问题
NullPointerException Problem when trying to mock Elastic Search's RestHighLevelClient
我在单元测试期间遇到 NullPointerException,当我试图在 ElasticClient
class:
中测试和模拟 RestHighLevelClient
时
@Configuration
@NoArgsConstructor
public class ElasticClient{
@Setter
private RestHighLevelClient restHighLevelClient;
@PostConstruct
public void buildRestHighLevelClient(){
RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(
"127.0.0.1",
9200, "http")
);
restClientBuilder.setRequestConfigCallback(
requestConfigBuilder ->
requestConfigBuilder
.setConnectTimeout(500000)
.setSocketTimeout(600000)
.setConnectionRequestTimeout(0)
)
.setHttpClientConfigCallback(
httpClientBuilder ->
httpClientBuilder
.setMaxConnPerRoute(2048)
);
restHighLevelClient = new RestHighLevelClient(restClientBuilder);
}
public boolean isReachable(){
return restHighLevelClient.ping(RequestOptions.DEFAULT);
}
}
和测试class:
@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
public class ElasticClientTest{
@Mock
private RestHighLevelClient restHighLevelClient;
ElasticClient elasticClient;
@Before
public void init(){
elasticClient = new ElasticClient();
elasticClient.setRestHighLevelClient(restHighLevelClient);
}
NullPointerException 来自这里:
@Test
public void whenElasticIsPingable_thenReturnTrue() throws IOException{
when(restHighLevelClient.ping(RequestOptions.DEFAULT)).thenReturn(true);
Assertions.assertThat(elasticClient.isReachable()).isTrue();
}
这是堆栈跟踪:
java.lang.NullPointerException
at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1764)
at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1734)
at org.elasticsearch.client.RestHighLevelClient.ping(RestHighLevelClient.java:694)
at com.example.ElasticClientTest.whenElasticIsPingable_thenReturnTrue(ElasticClientTest.java:44)
尝试:
when(restHighLevelClient.ping(eq(RequestOptions.DEFAULT))).thenReturn(true);
问题源于 RestHighLevelClient
中的 ping
方法是 final
因为不能定期模拟。
所以,我使用了this example的帮助关于PowerMock
最后的结果是:
@RunWith(PowerMockRunner.class)
@PrepareForTest(RestHighLevelClient.class)
public class ElasticClientTest{
ElasticClient elasticClient;
RestHighLevelClient restHighLevelClient;
@Before
public void init(){
restHighLevelClient = mock(RestHighLevelClient.class);
elasticClient = new ElasticClient();
elasticClient.setRestHighLevelClient(restHighLevelClient);
}
@Test
public void whenElasticIsPingable_thenReturnTrue() throws IOException{
when(restHighLevelClient.ping(RequestOptions.DEFAULT)).thenReturn(true);
Assertions.assertThat(elasticClient.isReachable()).isTrue();
}
您需要通过以下步骤添加 mockito 扩展以模拟最终对象:
- 在测试资源中创建名为“mockito-extensions”的文件夹
文件夹。
- 在里面添加一个名为“org.mockito.plugins.MockMaker”的文件
文件夹。
- 在该文件中,写入“mock-maker-inline”
我在单元测试期间遇到 NullPointerException,当我试图在 ElasticClient
class:
RestHighLevelClient
时
@Configuration
@NoArgsConstructor
public class ElasticClient{
@Setter
private RestHighLevelClient restHighLevelClient;
@PostConstruct
public void buildRestHighLevelClient(){
RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(
"127.0.0.1",
9200, "http")
);
restClientBuilder.setRequestConfigCallback(
requestConfigBuilder ->
requestConfigBuilder
.setConnectTimeout(500000)
.setSocketTimeout(600000)
.setConnectionRequestTimeout(0)
)
.setHttpClientConfigCallback(
httpClientBuilder ->
httpClientBuilder
.setMaxConnPerRoute(2048)
);
restHighLevelClient = new RestHighLevelClient(restClientBuilder);
}
public boolean isReachable(){
return restHighLevelClient.ping(RequestOptions.DEFAULT);
}
}
和测试class:
@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
public class ElasticClientTest{
@Mock
private RestHighLevelClient restHighLevelClient;
ElasticClient elasticClient;
@Before
public void init(){
elasticClient = new ElasticClient();
elasticClient.setRestHighLevelClient(restHighLevelClient);
}
NullPointerException 来自这里:
@Test
public void whenElasticIsPingable_thenReturnTrue() throws IOException{
when(restHighLevelClient.ping(RequestOptions.DEFAULT)).thenReturn(true);
Assertions.assertThat(elasticClient.isReachable()).isTrue();
}
这是堆栈跟踪:
java.lang.NullPointerException
at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1764)
at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1734)
at org.elasticsearch.client.RestHighLevelClient.ping(RestHighLevelClient.java:694)
at com.example.ElasticClientTest.whenElasticIsPingable_thenReturnTrue(ElasticClientTest.java:44)
尝试:
when(restHighLevelClient.ping(eq(RequestOptions.DEFAULT))).thenReturn(true);
问题源于 RestHighLevelClient
中的 ping
方法是 final
因为不能定期模拟。
所以,我使用了this example的帮助关于PowerMock
最后的结果是:
@RunWith(PowerMockRunner.class)
@PrepareForTest(RestHighLevelClient.class)
public class ElasticClientTest{
ElasticClient elasticClient;
RestHighLevelClient restHighLevelClient;
@Before
public void init(){
restHighLevelClient = mock(RestHighLevelClient.class);
elasticClient = new ElasticClient();
elasticClient.setRestHighLevelClient(restHighLevelClient);
}
@Test
public void whenElasticIsPingable_thenReturnTrue() throws IOException{
when(restHighLevelClient.ping(RequestOptions.DEFAULT)).thenReturn(true);
Assertions.assertThat(elasticClient.isReachable()).isTrue();
}
您需要通过以下步骤添加 mockito 扩展以模拟最终对象:
- 在测试资源中创建名为“mockito-extensions”的文件夹 文件夹。
- 在里面添加一个名为“org.mockito.plugins.MockMaker”的文件 文件夹。
- 在该文件中,写入“mock-maker-inline”