为何@TestPropertySource中静态变量的@Value注入返回null
解决Spring单元测试中@Value注入静态变量为null的问题
问题原因
Spring的@Value注解不支持直接注入静态字段——Spring依赖注入的对象是bean实例,静态字段属于类本身,不属于任何实例,因此容器不会对静态字段执行注入操作,导致你在@BeforeAll里看到theFoo为null。
解决方案
方案1:改用实例字段+@BeforeEach(推荐,符合Spring设计)
把静态字段改为实例字段,同时将@BeforeAll替换为@BeforeEach。@BeforeEach会在每个测试方法执行前触发,此时bean实例已完成初始化,注入的字段能正常取值:
@ContextConfiguration @TestPropertySource( properties = { "foo=bar", "baz=qux" }) @Testcontainers class MyUnitTest { @Value("${foo}") private String theFoo; @BeforeEach void setUp() { LOG.info("foo={}", theFoo); // 输出foo=bar } }
方案2:通过setter方法注入静态字段
如果必须保留静态字段和@BeforeAll,可以编写一个非静态的setter方法,用@Value注解该方法,在方法内部给静态字段赋值:
@ContextConfiguration @TestPropertySource( properties = { "foo=bar", "baz=qux" }) @Testcontainers class MyUnitTest { private static String theFoo; @Value("${foo}") public void setTheFoo(String foo) { MyUnitTest.theFoo = foo; } @BeforeAll static void setUp() { LOG.info("foo={}", theFoo); // 输出foo=bar } }
方案3:通过ApplicationContext获取配置
让测试类实现ApplicationContextAware接口,拿到Spring上下文后,直接从环境变量中读取配置值:
@ContextConfiguration @TestPropertySource( properties = { "foo=bar", "baz=qux" }) @Testcontainers class MyUnitTest implements ApplicationContextAware { private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { context = applicationContext; } @BeforeAll static void setUp() { String theFoo = context.getEnvironment().getProperty("foo"); LOG.info("foo={}", theFoo); // 输出foo=bar } }
内容的提问来源于stack exchange,提问作者Rick DeBay
相关产品推荐
相关产品推荐

