我尝试使用 Spring 中的 Value 注释来读取本地 application.yaml 文件,该文件与我的主测试类和单元测试类放在同一个包中。我有一个简单的类,其中包含获取配置值的方法:
public class EmailValidator {
String getConfigValue(configurationProvider1 configurationReader, String configName) {
String value = null;
ConfigurationProvider reader;
try {
reader = configurationReader.configurationProvider();
value = reader.getProperty(configName, String.class);
//the `reader` above is null when I run the test, so I get Null Pointer Exception on this line
if (value == null) {
LOGGER.warn("The configuration for " + configName + " cannot be found.");
}
} catch (Exception e){
e.printStackTrace();
}
return value;
}
}
我有一个配置提供程序类,它设置配置读取器,以便我上面的类可以使用它来读取 application.yaml 文件:
@Configuration
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@NoArgsConstructor
@ComponentScan
public class configurationProvider1 {
@Value("${configFilesPath:./domain/application.properties}")//Not really sure if this is the right way of locating my configuration file
@Getter
private String filePath;
@Bean
public ConfigurationProvider configurationProvider() throws FileNotFoundException {
if (!Paths.get(this.filePath).toFile().exists()) {
throw new FileNotFoundException("Configuration file doesn't exist: " + this.filePath);
}
ConfigFilesProvider configFilesProvider =
() -> Collections.singletonList(Paths.get(filePath).toAbsolutePath());
ConfigurationSource source = new FilesConfigurationSource(configFilesProvider);
Environment environment = new ImmutableEnvironment(this.filePath);
return new ConfigurationProviderBuilder()
.withConfigurationSource(source)
.withEnvironment(environment)
.build();
}
}
如上所述,我不确定 @Value("${configFilesPath:./domain/application.properties}")
是否是定位本地 application.properties 文件的正确方法(这些类位于同一个名为 domain
的包中,但配置文件不在资源文件夹中,因为这是一个服务层。所以它就在 domain
包下)。
当我尝试在第一个类中测试 getConfigValue 方法时,我得到了 NPE(我认为这是因为我作为参数传递给 getConfigValue 方法的 ConfigurationReader 为 null):
@RunWith(SpringRunner.class)
@SpringBootTest
public class EmailValidatorTest {
@MockBean
private configurationProvider1 configurationReader = mock(configurationProvider1.class);
@Autowired
private DefaultEmailValidator validator;//maybe I should inject the dependency somewhere?
@Test
public void simple(){
String a = validator.getConfigValue(configurationReader,"mail.subject.max.length");
System.out.println(a);
}
我不确定我的类此时是否实际上正在从配置文件中读取配置值。任何帮助将不胜感激!
附注代码已更新
最佳答案
@Value
Spring’s @Value annotation provides a convenient way to inject property values into components, not to provide the properties file path
@PropertySource 使用@PropertySource Doc
Annotation providing a convenient and declarative mechanism for adding a PropertySource to Spring's Environment. To be used in conjunction with
@Configuration
classesGiven a file app.properties containing the key/value pair
testbean.name=myTestBean
, the following@Configuration
class uses@PropertySourc
e to contributeapp.properties
to the Environment's set of PropertySources.
示例
@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setName(env.getProperty("testbean.name"));
return testBean;
}
}
YAML files cannot be loaded by using the
@PropertySource
annotation. So, in the case that you need to load values that way, you need to use a properties file.
来到测试用例,您不应该创建 DefaultEmailValidator
的新实例,您需要使用 @SpringBootTest
@SpringBootTest Example
The
@SpringBootTest
annotation can be used when we need to bootstrap the entire container. The annotation works by creating the ApplicationContext that will be utilized in our tests.
RunWith(SpringRunner.class)
@RunWith(SpringRunner.class) is used to provide a bridge between Spring Boot test features and JUnit. Whenever we are using any Spring Boot testing features in out JUnit tests, this annotation will be required.
@MockBean
Another interesting thing here is the use of @MockBean. It creates a Mock
EmailValidator测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class EmailValidatorTest {
@MockBean
private configurationProvider1 configurationReader;
@Autowire
private DefaultEmailValidator validator
@Test
public void testGetConfigValue(){
String a = validator.getConfigValue(configurationReader,"mail.subject.max.length");
System.out.println(a);
}
关于java - Spring - 使用值注释从本地配置文件中读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55787296/