You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JUnit5的TestExecutionListener中注入Spring Environment?

解决方案

你的分析完全正确:JUnit平台的TestExecutionListener由JUnit自行实例化,不受Spring容器管理,且testPlanExecutionStarted执行时Spring测试上下文还未初始化,因此直接用@Autowired注入Environment必然失败。以下是两种可行方案:

方案一:改用Spring测试框架的TestExecutionListener

如果你的监听逻辑不需要在整个测试计划启动时执行,而是可以在单个测试类/方法的生命周期阶段执行,推荐使用Spring官方提供的TestExecutionListener(属于org.springframework.test.context包),它由Spring的测试上下文管理器管理,天然支持依赖注入,且执行时机在Spring上下文初始化之后。

步骤1:实现Spring的TestExecutionListener

import org.springframework.core.env.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.test.context.TestExecutionListener;
import org.springframework.test.context.TestContext;

@Component
public class MySpringTestListener implements TestExecutionListener {

    @Autowired
    private Environment env;

    @Override
    public void beforeTestClass(TestContext testContext) throws Exception {
        // 此时Spring上下文已完全初始化,env可正常使用
        System.out.println("当前应用名称:" + env.getProperty("spring.application.name"));
    }

    // 可按需实现其他生命周期方法,如beforeTestMethod、afterTestMethod等
}

步骤2:在测试类中注册监听器

在你的@SpringBootTest测试类上添加@TestExecutionListeners注解,将自定义监听器注册进去,同时设置mergeMode保留Spring默认的监听器:

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestExecutionListeners;

@SpringBootTest
@TestExecutionListeners(listeners = MySpringTestListener.class, mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
public class SampleTest {
    // 测试方法
}

方案二:保留JUnit平台TestExecutionListener,延迟获取Spring上下文

如果你必须监听整个测试计划的启动事件(如testPlanExecutionStarted),可以在后续测试执行阶段(第一个Spring测试类启动时)获取已初始化的Spring上下文,进而拿到Environment。

实现代码

import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.launcher.TestIdentifier;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.TestContext;

public class MyPlatformTestListener implements TestExecutionListener {

    private Environment env;

    @Override
    public void testPlanExecutionStarted(TestPlan testPlan) {
        // 此时Spring上下文未初始化,无法获取env
        System.out.println("测试计划启动");
    }

    @Override
    public void executionStarted(TestIdentifier testIdentifier) {
        // 仅在第一次成功获取env时执行
        if (env == null) {
            try {
                // 通过SpringExtension获取当前测试的上下文(仅对Spring测试类有效)
                TestContext testContext = SpringExtension.getTestContext(testIdentifier.getSource().get());
                env = testContext.getApplicationContext().getEnvironment();
                // 此时env已可用
                System.out.println("获取到Environment:" + env.getProperty("spring.profiles.active"));
            } catch (Exception e) {
                // 非Spring测试类会抛出异常,直接忽略即可
            }
        }
    }
}

注册监听器

在src/test/resources/META-INF/services目录下创建文件org.junit.platform.launcher.TestExecutionListener,文件内容为自定义监听器的全限定类名,例如:

com.example.MyPlatformTestListener

JUnit平台会自动扫描并加载这个监听器。

内容的提问来源于stack exchange,提问作者user3364652

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 01:24:28