使用ESIntegTestCase运行JUnit测试报错,求解决方法
你提到正在用ESIntegTestCase编写Elasticsearch 6.1.1的集成测试,测试类代码如下:
@RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) @ClusterScope(scope=SUITE, numDataNodes = 3) public class SampleClassTest1 extends ESIntegTestCase{ .... }
但运行时始终抛出如下异常:
Suppressed: java.lang.IllegalStateException: No context information for thread: Thread[id=16, name=Thread-1, state=RUNNABLE, group=TGRP-SampleClassTest]. Is this thread running under a class com.carrotsearch.randomizedtesting.RandomizedRunner runner context? Add @RunWith(class com.carrotsearch.randomizedtesting.RandomizedRunner.class) to your test class. Make sure your code accesses random contexts within @BeforeClass and @AfterClass boundary (for example, static test class initializers are not permitted to access random contexts).
针对这个问题,我给你几个具体的排查和解决方向:
排查静态初始化逻辑:错误提示明确提到静态初始化器不能访问随机上下文,你先检查测试类(或者你可能继承的自定义基类)里有没有静态代码块、静态变量初始化时调用了RandomizedRunner提供的随机方法(比如
randomBoolean()、randomInt()),或者访问了ES集群的上下文资源。这类操作必须放在@BeforeClass注解标记的方法里,绝对不能在静态初始化阶段执行。确认依赖与注解的正确性:虽然你已经添加了
@RunWith(RandomizedRunner.class),但还是要检查:- 注解有没有拼写错误,比如类路径是否正确;
- 项目依赖是否存在版本冲突:Elasticsearch 6.1.1依赖特定版本的carrotsearch randomizedtesting库,确保你的测试依赖和ES本身的依赖版本完全一致,避免因类加载问题导致上下文无法初始化。
检查线程执行边界:报错里的Thread-1是在RandomizedRunner的管理上下文之外运行的,说明你可能在异步线程、或者静态初始化时启动的线程里调用了需要ES测试上下文的方法。所有涉及ES集群操作、随机上下文访问的代码,都必须在
@BeforeClass、@Test、@AfterClass这些Runner管理的方法内部执行,不能在脱离Runner控制的线程中调用。验证@ClusterScope配置与继承关系:
@ClusterScope(scope=SUITE, numDataNodes=3)本身配置没问题,但要确认你的测试类没有继承其他自定义测试基类,导致注解被覆盖或者上下文初始化流程被破坏。如果有自定义基类,要确保基类也正确使用了RandomizedRunner,并且没有修改默认的上下文初始化逻辑。简化测试代码定位问题:先把测试类里的业务逻辑全部注释掉,只保留最基础的继承结构和一个空的
@Test方法,看能不能正常启动集群。如果可以正常运行,再逐步恢复代码,定位到导致上下文异常的具体代码段。
内容的提问来源于stack exchange,提问作者Manik Vij

