Spring 'application.yml' 中的引导属性未从 JUnit 测试加载
Spring Boot properties in 'application.yml' not loading from JUnit Test
我做错了什么?我正在使用这个运行并找到我的 src/main/resources/config/application.yml
的小型独立应用程序。相同的配置不适用于 JUnit,见下文:
@Configuration
@ComponentScan
@EnableConfigurationProperties
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class);
}
}
@Component
@ConfigurationProperties
public class Bean{
...
}
以下不起作用,application.yml
中的相同属性未加载且 Bean
只有 null
个值:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestApplication.class)
public class SomeTestClass {
...
}
试试这个:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestApplication.class,
initializers = ConfigFileApplicationContextInitializer.class)
public class SomeTestClass {
...
}
编辑:
对于 Spring 引导版本 1.5+,删除了 SpringApplicationConfiguration
以支持 SpringBootTest
或直接使用 SpringBootContextLoader
。
您仍然可以使用带有 ContextConfiguration
注释的 initializers
参数。
这是另一种方式:[Spring Boot v1.4.x]
@Configuration
@ConfigurationProperties(prefix = "own")
public class OwnSettings {
private String name;
Getter & setters...
}
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@BootstrapWith(SpringBootTestContextBootstrapper.class)
public class OwnSettingsTest {
@Autowired
private OwnSettings bean;
@Test
public void test() {
bean.getName();
}
}
仅当 'application.properties' 文件存在时才有效。
例如Maven 项目:
src/main/resources/application.properties [ 文件可以为空但必须填写! ]
src/main/resources/application.yml [这是你真正的配置文件]
2017 年 2 月备选方案:
@SpringBootTest
@ContextConfiguration(classes = { TestApplication.class })
@RunWith(SpringRunner.class)
public class SomeTestClass {
...
}
精益变体(没有@SpringBootTest
):
@ContextConfiguration(classes = { TestApplication.class },
initializers = { ConfigFileApplicationContextInitializer.class })
@RunWith(SpringRunner.class)
public class SomeTestClass {
这个有效
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {
@Test
public void contextLoads() {
}
}
在我的例子中,我试图测试一个没有在常规应用程序类路径中声明 @SpringBootApp
的库,但我的测试上下文中确实有一个。在通过 Spring Boot 初始化过程调试我的方式后,我发现 Spring Boot 的 YamlPropertySourceLoader(从 1.5.2.RELEASE 开始)将不会加载 YAML 属性,除非 org.yaml.snakeyaml.Yaml
在类路径上。我的解决方案是在我的 POM 中添加 snakeyaml 作为测试依赖项:
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.19</version>
<scope>test</scope>
</dependency>
Spring 引导 2 示例:
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withInitializer(new ConfigFileApplicationContextInitializer());
@Test public void test() throws Exception {
this.contextRunner
.withUserConfiguration(TestApplication.class)
.run((context) -> {
.....
});
}
在 SpringBoot 2.0 w/o 中使用 @SpringBootTest
加载 any 自定义 yml 文件的技巧
- 在 test\resources
中创建一些 yml 文件
- 使用
ConfigFileApplicationContextInitializer
和spring.config.location
属性
示例代码:
@RunWith(SpringRunner.class)
@ContextConfiguration(
classes = { MyConfiguration.class, AnotherDependancy.class },
initializers = {ConfigFileApplicationContextInitializer.class} )
@TestPropertySource(properties = { "spring.config.location=classpath:myApp-test.yml" })
public class ConfigProviderTest {
@Autowired
private MyConfiguration myConfiguration; //this will be filled with myApp-test.yml
@Value("${my.config-yml-string}")
private String someSrting; //will get value from the yml file.
}
对于 JUnit 5,使用 @ExtendWith(SpringExtension.class)
注释而不是 @RunWith(SpringRunner.class)
使用 Spring 启动 2
的单元测试
spring boot 2 默认支持'application.properties',
对于 'application.yml' 只需在下面添加:
@TestPropertySource(properties = { "spring.config.location=classpath:application.yml" })
例如
@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(properties = { "spring.config.location=classpath:application.yml" })
public class ServiceTest {...}
添加到 Liam's ,替代方案是:
@TestPropertySource(locations = { "classpath:application.yaml" })
这里的主要区别在于,如果 application.yaml
不在您的 /test/resources
目录中
,测试将失败并出现文件未找到异常
延长Liam's
您可以添加 spring.config.additional-location=classpath:application-overrides.yaml
属性,这样来自默认位置的配置将与提供的其他配置合并:
@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(properties = {
"spring.config.additional-location=classpath:testcases/test-case-properties.yaml",
})
public class SpecificTestCaseIntegrationTest {
由于 spring-boot 版本 2.6.0 org.springframework.boot.test.context.ConfigFileApplicationContextInitializer
已弃用,建议使用 org.springframework.boot.test.context.ConfigDataApplicationContextInitializer
。
在您的测试中,您可以将其用作:
@ContextConfiguration(classes = {
...
}, initializers = ConfigDataApplicationContextInitializer.class)
public class MyTestingClassIT
我做错了什么?我正在使用这个运行并找到我的 src/main/resources/config/application.yml
的小型独立应用程序。相同的配置不适用于 JUnit,见下文:
@Configuration
@ComponentScan
@EnableConfigurationProperties
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class);
}
}
@Component
@ConfigurationProperties
public class Bean{
...
}
以下不起作用,application.yml
中的相同属性未加载且 Bean
只有 null
个值:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestApplication.class)
public class SomeTestClass {
...
}
试试这个:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestApplication.class,
initializers = ConfigFileApplicationContextInitializer.class)
public class SomeTestClass {
...
}
编辑:
对于 Spring 引导版本 1.5+,删除了 SpringApplicationConfiguration
以支持 SpringBootTest
或直接使用 SpringBootContextLoader
。
您仍然可以使用带有 ContextConfiguration
注释的 initializers
参数。
这是另一种方式:[Spring Boot v1.4.x]
@Configuration
@ConfigurationProperties(prefix = "own")
public class OwnSettings {
private String name;
Getter & setters...
}
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@BootstrapWith(SpringBootTestContextBootstrapper.class)
public class OwnSettingsTest {
@Autowired
private OwnSettings bean;
@Test
public void test() {
bean.getName();
}
}
仅当 'application.properties' 文件存在时才有效。
例如Maven 项目:
src/main/resources/application.properties [ 文件可以为空但必须填写! ]
src/main/resources/application.yml [这是你真正的配置文件]
2017 年 2 月备选方案:
@SpringBootTest
@ContextConfiguration(classes = { TestApplication.class })
@RunWith(SpringRunner.class)
public class SomeTestClass {
...
}
精益变体(没有@SpringBootTest
):
@ContextConfiguration(classes = { TestApplication.class },
initializers = { ConfigFileApplicationContextInitializer.class })
@RunWith(SpringRunner.class)
public class SomeTestClass {
这个有效
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {
@Test
public void contextLoads() {
}
}
在我的例子中,我试图测试一个没有在常规应用程序类路径中声明 @SpringBootApp
的库,但我的测试上下文中确实有一个。在通过 Spring Boot 初始化过程调试我的方式后,我发现 Spring Boot 的 YamlPropertySourceLoader(从 1.5.2.RELEASE 开始)将不会加载 YAML 属性,除非 org.yaml.snakeyaml.Yaml
在类路径上。我的解决方案是在我的 POM 中添加 snakeyaml 作为测试依赖项:
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.19</version>
<scope>test</scope>
</dependency>
Spring 引导 2 示例:
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withInitializer(new ConfigFileApplicationContextInitializer());
@Test public void test() throws Exception {
this.contextRunner
.withUserConfiguration(TestApplication.class)
.run((context) -> {
.....
});
}
在 SpringBoot 2.0 w/o 中使用 @SpringBootTest
- 在 test\resources 中创建一些 yml 文件
- 使用
ConfigFileApplicationContextInitializer
和spring.config.location
属性
示例代码:
@RunWith(SpringRunner.class)
@ContextConfiguration(
classes = { MyConfiguration.class, AnotherDependancy.class },
initializers = {ConfigFileApplicationContextInitializer.class} )
@TestPropertySource(properties = { "spring.config.location=classpath:myApp-test.yml" })
public class ConfigProviderTest {
@Autowired
private MyConfiguration myConfiguration; //this will be filled with myApp-test.yml
@Value("${my.config-yml-string}")
private String someSrting; //will get value from the yml file.
}
对于 JUnit 5,使用 @ExtendWith(SpringExtension.class)
注释而不是 @RunWith(SpringRunner.class)
使用 Spring 启动 2
的单元测试spring boot 2 默认支持'application.properties', 对于 'application.yml' 只需在下面添加:
@TestPropertySource(properties = { "spring.config.location=classpath:application.yml" })
例如
@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(properties = { "spring.config.location=classpath:application.yml" })
public class ServiceTest {...}
添加到 Liam's
@TestPropertySource(locations = { "classpath:application.yaml" })
这里的主要区别在于,如果 application.yaml
不在您的 /test/resources
目录中
延长Liam's
您可以添加 spring.config.additional-location=classpath:application-overrides.yaml
属性,这样来自默认位置的配置将与提供的其他配置合并:
@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(properties = {
"spring.config.additional-location=classpath:testcases/test-case-properties.yaml",
})
public class SpecificTestCaseIntegrationTest {
由于 spring-boot 版本 2.6.0 org.springframework.boot.test.context.ConfigFileApplicationContextInitializer
已弃用,建议使用 org.springframework.boot.test.context.ConfigDataApplicationContextInitializer
。
在您的测试中,您可以将其用作:
@ContextConfiguration(classes = {
...
}, initializers = ConfigDataApplicationContextInitializer.class)
public class MyTestingClassIT