如何使用@ExtendWith(SpringExtension.class)从application.properties加载属性

问题描述 投票:0回答:1

我正在尝试学习 Spring Boot,并且我试图对测试有一个扎实的了解。

我知道 @SpringBootTest 加载了完整的上下文,我不想这样做。 我知道切片测试(即:@WebMvcTest、@JdbcTest)内部使用@ExtendWith(SpringExtension.class), 如果我只想使用自己的 bean 进行简单的集成测试,并且还想加载配置属性,是否可以将其与 @Value 一起使用?

我知道我可以使用 ReflectionTestUtils,但我想既然 Spring Extension 加载了一个测试上下文,它应该获取 application.properties 文件?

到目前为止,我用@Value得到了一个非常奇怪的结果,它获取的是键而不是值。它与 @SpringBootTest 完美配合,所以我知道在完整应用程序时属性加载得很好。

这是我的代码:

src/test/resources 中的application.properties:

misc.test-prop-value=testPropValue

@ExtendWith(SpringExtension.class) 公共类 ConfigPropertiesTest {

@Value( value = "${misc.test-prop-value}")
private String testPropValue;


@Value("${some.non.existent.value}")
private String nonExistentValue;

@Test
void testNonExistentValue() {
    assertNull(nonExistentValue); // Fails, the value is: ${some.non.existent.value}
}

@Test
public void testConfigProperties() {
    assertEquals("testPropValue", testPropValue); //Fails, the value is: ${misc.test-prop-value}
}

}

为什么@Value 自己获取密钥?

它与@SpringBootTest完美配合,

我想既然@SpringExtension加载了应用程序上下文:

@ExtendWith(SpringExtension.class)
public class SpringExtensionBasicTest {

    @Autowired
    private ApplicationContext applicationContext;

    @Test
    void contextLoads() throws Exception {
        //GenericApplicationContext instance:
        System.out.println("Context instance: " + applicationContext.getClass());
        assertNotNull(applicationContext); // Test passes
    }



}

当我扩展具有@SpringBootTest的基类时, 一切正常,它加载上下文,甚至在找不到 some.non.existent.value 属性时出现错误。 但使用 Spring 扩展时,行为很奇怪。

也许这是一个愚蠢的问题,我可以感觉到这是其中之一,我在脸上遗漏了一些如此明显的东西,以至于没有人解释它,但我不明白。 另外,如果我想要自己的切片测试,但我仍然希望像 @JdbcTest 一样加载 .properties 文件,那么这将如何工作

编辑:

使用@TestPropertySource时,我通过了两个测试,但是@SpringBootTest中不存在的值为null的值仍然显示相同的键:

@ExtendWith(SpringExtension.class)
@TestPropertySource(value = "classpath:application.properties")
public class ConfigPropertiesTest  {

    @Value( value = "${misc.test-prop-value}")
    private String testPropValue;

    @Value("${family.mother}")
    private String mamaValue;

    /**
     * When a non-existent value is there,
     * It is not null for some strange reason,
     * But it still shows the key
     */
    @Value("${some.non.existent.value}")
    private String nonExistentValue;

    @Test
    void testNonExistentValue() {
        //Still shows ${some.non.existent.value}
        assertNull(nonExistentValue);
    }

    @Test
    void testPropValue1() {
        assertEquals("Mama-test", mamaValue); //Ok
    }

    @Test
    public void testConfigProperties() {
        assertEquals("testPropValue", testPropValue); //Ok
    }

}
java spring-boot testing junit5
1个回答
0
投票

我认为您的 IgnoreUnresolvablePlaceholders 参数设置为 true。否则,缺少

${some.non.existent.value}
属性将导致错误
java.lang.IllegalArgumentException: Could not resolve placeholder 'some.non.existent.value' in value "${some.non.existent.value}"

例如,如果您创建这样的 bean:

    @Bean
    public PropertySourcesPlaceholderConfigurer propertyConfig() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        configurer.setIgnoreUnresolvablePlaceholders(true);
        return configurer;
    }

然后,如果 Spring 找不到 nonExistentValue 字段的

some.non.existent.value
属性,它将把值
"${some.non.existent.value}"
写入该字段。

我认为您使用以下代码为 nonExistentValue 字段设置默认值是有意义的:

    @Value("${some.non.existent.value:#{null}}")
    private String nonExistentValue;
© www.soinside.com 2019 - 2024. All rights reserved.