Quarkus JBeret:作业完成后能否获取JobContext?
在Quarkus JBeret集成测试中获取JobContext的transientData
直接通过JobOperator获取的JobExecution是作业的持久化元数据,并不包含运行时的JobContext实例——JobContext是作业执行过程中的上下文对象,仅在作业运行时可访问。要测试transientData里的值,需要在作业执行阶段捕获JobContext,并将数据传递到测试代码中,具体可以通过自定义JobListener实现:
步骤1:编写测试用JobListener
创建一个JobListener实现类,注入JobContext后,将transientData存储到线程安全的容器中,关联对应的作业执行ID:
import jakarta.batch.api.listener.JobListener; import jakarta.batch.runtime.context.JobContext; import jakarta.inject.Inject; import jakarta.enterprise.context.ApplicationScoped; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @ApplicationScoped public class TestJobListener implements JobListener { @Inject JobContext jobContext; // 存储作业执行ID对应的transientData,线程安全容器适配JBeret的多线程执行 public static final Map<Long, Map<String, Object>> jobTransientData = new ConcurrentHashMap<>(); @Override public void beforeJob() throws Exception { // 若需要作业启动时的transientData,在此存储 jobTransientData.put(jobContext.getExecutionId(), jobContext.getTransientUserData()); } @Override public void afterJob() throws Exception { // 若需要作业执行完成后的最终transientData,在此更新 jobTransientData.put(jobContext.getExecutionId(), jobContext.getTransientUserData()); } }
步骤2:在作业XML中配置Listener
将自定义的TestJobListener添加到你的作业配置XML中,确保作业执行时会触发该监听器:
<job id="your-target-job" xmlns="http://xmlns.jcp.org/xml/ns/javaee"> <listeners> <listener ref="testJobListener"/> </listeners> <!-- 原有的Step配置 --> <step id="your-step"> <!-- Step具体定义 --> </step> </job>
步骤3:在测试中获取并验证transientData
启动作业后,先等待作业执行完成(因为JobOperator.start是异步执行),再从监听器的容器中取出对应作业的transientData进行验证:
@Test void verifyJobTransientData() throws InterruptedException { // 启动目标作业 JobExecutionImpl jobExecution = startJob("your-job.xml", new Properties()); // 等待作业执行完成,循环查询状态直到非运行态 while (jobExecution.getBatchStatus().isRunning()) { Thread.sleep(100); jobExecution = (JobExecutionImpl) jobOperator.getJobExecution(jobExecution.getExecutionId()); } // 从监听器容器中获取transientData Map<String, Object> transientData = TestJobListener.jobTransientData.get(jobExecution.getExecutionId()); // 执行断言验证 assertNotNull("Transient data should not be null", transientData); assertEquals("Expected value for key 'test-key'", "test-value", transientData.get("test-key")); // 清理测试数据,避免影响其他测试用例 TestJobListener.jobTransientData.remove(jobExecution.getExecutionId()); }
注意事项
- 若使用
JobOperator.startAndWait方法启动作业,可省略手动等待的逻辑,该方法会阻塞直到作业完成。 TestJobListener需要被CDI管理(如添加@ApplicationScoped),否则无法成功注入JobContext。- 若需要验证
StepContext的transientData,可采用相同思路,实现StepListener并存储对应数据。
内容的提问来源于stack exchange,提问作者Ionut
相关产品推荐
相关产品推荐

