我正在尝试将嵌入式Elasticsearch添加到我的Spring Boot集成测试中。这里的问题是初始化节点无法与Spring Boot一起使用,因为两者都应使用不同的测试运行器。
这是我得到的错误:
java.lang.IllegalStateException:没有线程的上下文信息:Thread [id = 1,name = main,state = RUNNABLE,group = main]。该线程是否在com.carrotsearch.randomizedtesting.RandomizedRunner运行器上下文环境下运行?将@RunWith(class com.carrotsearch.randomizedtesting.RandomizedRunner.class)添加到测试类。确保您的代码访问@BeforeClass和@AfterClass边界内的随机上下文(例如,不允许静态测试类初始化程序访问随机上下文)。
这是我的课程:
@ActiveProfiles("test")
@Profile("test")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Application.class})
public class ExampleTest extends AbstractElasticSearchIntegrationTest{
@Autowired
ExampleController exampleController;
@Test
public void deleteExample() throws Exception {
assert(exampleController.delete("foo",
"bar",
null)).equals(new ResponseEntity<DefaultResponse> .
(HttpStatus.OK));
}
}
我的嵌入式Elasticsearch类与此类似:
@Slf4j
@Configuration
@Profile("test")
public class EmbeddedElasticSearchServer {
private static final String DEFAULT_DATA_DIRECTORY = "target/elasticsearch-data";
private static final String NODE_LOCAL_PROP = "node.local";
private static final String CLUSTER_NAME_PROP = "cluster.name";
private static final String INDEX_GATEWAY_TYPE_PROP = "index.gateway.type";
private static final String PATH_HOME_PROP = "path.home";
private static final String PATH_DATA_PROP = "path.data";
private static final String HTTP_ENABLED_PROP = "http.enabled";
private static final String DEFAULT_DATA_DIR = "target/es-data";
private static final String DEFAULT_CLUSTER = "cluster";
private Node node;
private String dataDirectory;
public EmbeddedElasticSearchServer() {
this(DEFAULT_DATA_DIRECTORY);
}
public EmbeddedElasticSearchServer(String dataDirectory) {
this.dataDirectory = dataDirectory;
Settings elasticsearchSettings = Settings.builder()
.put(PATH_HOME_PROP, "target")
.put("http.type", "netty4")
.put(PATH_DATA_PROP, dataDirectory.toString())
.put(CLUSTER_NAME_PROP, DEFAULT_CLUSTER)
.put("http.port", 4040)
.put("transport.type", "netty4")
.build();
try {
Collection plugins = Arrays.asList(Netty4Plugin.class);
node = new PluginConfigurableNode(elasticsearchSettings, plugins).start();
}
catch (Exception e) {
e.printStackTrace();
}
}
public Client getClient() {
return node.client();
}
public RestClient getRestClient() {
RestClient restClient = getRestClientBuilder().build();
return restClient;
}
private RestClientBuilder getRestClientBuilder() {
RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost("localhost", 4040, "http"))
.setRequestConfigCallback((b) -> customizedRequestConfig(b))
.setHttpClientConfigCallback((b) -> customizedHttpClientConfig(b))
.setMaxRetryTimeoutMillis(5000);
return restClientBuilder;
}
public RestHighLevelClient getRestHighLevelClient() {
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(getRestClientBuilder());
return restHighLevelClient;
}
private RequestConfig.Builder customizedRequestConfig(RequestConfig.Builder builder) {
return builder
.setConnectionRequestTimeout( 0 )
.setSocketTimeout(5000)
.setConnectTimeout(5000 );
}
private HttpAsyncClientBuilder customizedHttpClientConfig(HttpAsyncClientBuilder builder) {
log.info("Setting connection pool, maximum connection {}", 200);
builder.setMaxConnPerRoute(20)
.setMaxConnTotal(200);
return builder;
}
@AfterClass
public void shutdown() {
try {
node.close();
} catch (IOException e) {
e.printStackTrace();
}
deleteDataDirectory();
}
@AfterClass
private void deleteDataDirectory() {
try {
FileUtils.deleteDirectory(new java.io.File(dataDirectory));
} catch (IOException e) {
throw new RuntimeException("Could not delete data directory of embedded elasticsearch server", e);
}
}
private static class PluginConfigurableNode extends Node {
public PluginConfigurableNode(Settings settings, Collection<Class<? extends Plugin>> classpathPlugins) {
super(InternalSettingsPreparer.prepareEnvironment(settings, null), classpathPlugins);
}
}
现在,如果不是针对SpringJUnit4Runner,则将运行测试,但这是初始化应用程序所需的bean所必需的。
我必须遵守的另一个约束是,要在应用程序中初始化的Bean之一需要连接到嵌入式Elasticsearch进行初始化。那么,有没有办法解决这两个问题?
谢谢