2014-01-21 26 views
49

Spring Boot允許我們用與YAML等價的方式替換我們的application.properties文件。然而,我似乎在測試中遇到了困難。如果我註釋我的TestConfiguration(一個簡單的Java配置),它期望一個屬性文件。Spring @PropertySource使用YAML

例如這不起作用: @PropertySource(value = "classpath:application-test.yml")

如果我有這在我的YAML文件:

db: 
    url: jdbc:oracle:thin:@pathToMyDb 
    username: someUser 
    password: fakePassword 

而且我會充分利用這些價值的東西是這樣的:

@Value("${db.username}") String username 

但是,我結束了,像這樣的錯誤:

Could not resolve placeholder 'db.username' in string value "${db.username}" 

如何在我的測試中利用YAML的優點?

+0

定義「是行不通的。」有什麼異常/錯誤/警告? –

+0

Spring Boot展平YAML文件,使其顯示爲帶點符號的屬性文件。扁平化沒有發生。 – checketts

+0

只是爲了確認,這適用於非測試代碼? –

回答

28

春天引導有這樣的幫手,只需添加

@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class) 

在你的測試類的頂部或抽象測試超類。

+1

這不工作對我來說,沒有加載性能。 –

9

加載yaml屬性的方法,恕我直言可以通過兩種方式完成:

a。您可以將配置置於標準位置 - application.yml位於類路徑根目錄中 - 通常爲src/main/resources,並且此yaml屬性應自動通過Spring引導加載,並帶有您提到的扁平路徑名。

b。第二種方法是一個小更廣泛,基本上是定義一個類來保存你的屬性是這樣的:根據「分貝的根元素

@ConfigurationProperties(path="classpath:/appprops.yml", name="db") 
public class DbProperties { 
    private String url; 
    private String username; 
    private String password; 
... 
} 

所以基本上這是說,負載YAML文件,並填充DbProperties類」。

我們用它在任何類,你將不得不這樣做:

@EnableConfigurationProperties(DbProperties.class) 
public class PropertiesUsingService { 

    @Autowired private DbProperties dbProperties; 

} 

這些方法的執行應該爲你工作乾淨利落地使用Spring啓動。

+0

確保你的classpath中有snakeyml,並且上面應該可以工作。 – hoserdude

+3

這些天來(雖然不是在這個問題被問的時間),'snakeyaml'被拉入由'彈簧引導starter'傳遞依賴,所以應該沒有必要將它添加到你的'pom.xml'或'build.gradle',除非你有根深蒂固的使用不同版本的衝動。 :) – Steve

+1

它現在是'locations',而不是'path',並且'ConfigFileApplicationContextInitializer'也是必需的。 – OrangeDog

19

@PropertySource只支持屬性文件(這是Spring的限制,不是引導本身)。隨意打開功能請求票in JIRA

+0

我希望有一種方法可以重新使用yaml監聽器,或者手動將yaml加載到可以傳遞到測試配置的環境中。 – checketts

+10

我想你可以寫一個'ApplicationContextInitializer'並將其添加到測試配置(只使用一個'YamlPropertySourceLoader'提升'Environment')。就個人而言,如果'@ PropertySource'原生支持這種行爲,我更喜歡它。 –

+0

這仍然是這種情況? '@PropertySource'不支持YAML嗎? – domi

0

這是因爲你還沒有配置snakeyml。 春季開機提供了@EnableAutoConfiguration功能。 有snakeyml配置太當u調用這個註解..

這是我的方式:

@Configuration 
@EnableAutoConfiguration 
public class AppContextTest { 
} 

這裏是我的測試:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(
     classes = { 
       AppContextTest.class, 
       JaxbConfiguration.class, 
     } 
) 

public class JaxbTest { 
//tests are ommited 
} 
3

我找到了一個解決方法,通過使用@ActiveProfiles("test")和添加一個application-test.yml文件到src/test/resources。

它結束了看起來像這樣:

@SpringApplicationConfiguration(classes = Application.class, initializers = ConfigFileApplicationContextInitializer.class) 
@ActiveProfiles("test") 
public abstract class AbstractIntegrationTest extends AbstractTransactionalJUnit4SpringContextTests { 

} 

文件應用test.yml只包含我想從application.yml替換的屬性(可在SRC /主/資源中找到) 。

+0

這就是我正在嘗試使用的。由於某些原因,當我使用'@Value(「$ {my.property}」)時它不起作用(Spring Boot 1.3.3)'但是如果我使用'environment.getProperty(「my.property」),它工作正常'。 –

1

我需要閱讀一些性質爲我的代碼,這可與彈簧引導1.3.0.RELEASE

@Autowired 
private ConfigurableListableBeanFactory beanFactory; 

// access a properties.yml file like properties 
@Bean 
public PropertySource properties() { 
    PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer(); 
    YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean(); 
    yaml.setResources(new ClassPathResource("properties.yml")); 
    propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject()); 
    // properties need to be processed by beanfactory to be accessible after 
    propertySourcesPlaceholderConfigurer.postProcessBeanFactory(beanFactory); 
    return propertySourcesPlaceholderConfigurer.getAppliedPropertySources().get(PropertySourcesPlaceholderConfigurer.LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME); 
} 
1

在測試單元@value具有從屬性文件,以便ü可以使用呼叫特性的一些問題環境更換值

@Autowired 
private Environment environment; 
public void init(){ 

    String username=environment.getRequiredProperty("db.username"); 

} 

這樣你就可以立即致電酒店在製作和測試單元

25

至於有人提到@PropertySource不加載yaml文件。解決方法是自行加載文件,並將加載的屬性添加到Environment

Implemement ApplicationContextInitializer

public class YamlFileApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { 
    @Override 
    public void initialize(ConfigurableApplicationContext applicationContext) { 
    try { 
     Resource resource = applicationContext.getResource("classpath:file.yml"); 
     YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader(); 
     PropertySource<?> yamlTestProperties = sourceLoader.load("yamlTestProperties", resource, null); 
     applicationContext.getEnvironment().getPropertySources().addFirst(yamlTestProperties); 
    } catch (IOException e) { 
     throw new RuntimeException(e); 
    } 
    } 
} 

您初始化添加到您的測試:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = Application.class, initializers = YamlFileApplicationContextInitializer.class) 
public class SimpleTest { 
    @Test 
    public test(){ 
    // test your properties 
    } 
} 
+0

其實這應該是最好的答案,謝謝它的工作! – Adelin

+0

這是否解決了https://jira.spring.io/browse/SPR-13912? – bobmarksie

4

另一種選擇是設置spring.config.location通過@TestPropertySource

@TestPropertySource(properties = { "spring.config.location = classpath:<path-to-your-yml-file>" } 
7

從春天啓動1.4,您可以使用新的@SpringBootTest註釋通過使用Spring Boot支持引導您的集成測試來更輕鬆地實現此目的(並簡化您的集成測試設置)。

有關Spring Blog的詳細信息。

據我所知,這意味着您可以像生產代碼一樣獲得Spring Boot的所有好處,包括自動從類路徑中獲取YAML配置。

默認情況下,該註釋將

...第一次嘗試從任何內部的類加載@Configuration,如果失敗,它將搜索您的主@SpringBootApplication類。

但您可以指定其他配置類(如果需要)。

對於這種特殊情況,您可以將@SpringBootTest@ActiveProfiles("test")結合起來,假如它遵循正常的啓動命名標準(即application-test.yml),Spring將選擇您的YAML配置。

@RunWith(SpringRunner.class) 
@SpringBootTest 
@ActiveProfiles("test") 
public class SpringBootITest { 

    @Value("${db.username}") 
    private String username; 

    @Autowired 
    private MyBean myBean; 

    ... 

} 

注:SpringRunner.class是在春季啓動多個配置文件配置SpringJUnit4ClassRunner.class

0

加載自定義文件陽明海運的新名稱。

1)添加屬性豆與SpringBootApplication啓動如下

@SpringBootApplication 
@ComponentScan({"com.example.as.*"}) 
public class TestApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(TestApplication.class, args); 
    } 

    @Bean 
    @Profile("dev") 
    public PropertySourcesPlaceholderConfigurer propertiesStage() { 
     return properties("dev"); 
    } 

    @Bean 
    @Profile("stage") 
    public PropertySourcesPlaceholderConfigurer propertiesDev() { 
     return properties("stage"); 
    } 

    @Bean 
    @Profile("default") 
    public PropertySourcesPlaceholderConfigurer propertiesDefault() { 
     return properties("default"); 

    } 
    /** 
    * Update custom specific yml file with profile configuration. 
    * @param profile 
    * @return 
    */ 
    public static PropertySourcesPlaceholderConfigurer properties(String profile) { 
     PropertySourcesPlaceholderConfigurer propertyConfig = null; 
     YamlPropertiesFactoryBean yaml = null; 

     propertyConfig = new PropertySourcesPlaceholderConfigurer(); 
     yaml = new YamlPropertiesFactoryBean(); 
     yaml.setDocumentMatchers(new SpringProfileDocumentMatcher(profile));// load profile filter. 
     yaml.setResources(new ClassPathResource("env_config/test-service-config.yml")); 
     propertyConfig.setProperties(yaml.getObject()); 
     return propertyConfig; 
    } 
} 

2)配置了Java POJO對象如下

@Component 
@JsonIgnoreProperties(ignoreUnknown = true) 
@JsonInclude(Include.NON_NULL) 
@ConfigurationProperties(prefix = "test-service") 
public class TestConfig { 

    @JsonProperty("id") 
    private String id; 

    @JsonProperty("name") 
    private String name; 

    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 

3)創建自定義的陽明海運(下放置資源路徑如下, YML文件名:test-service-config.yml

例如配置在yml文件中

test-service: 
    id: default_id 
    name: Default application config 
--- 
spring: 
    profiles: dev 

test-service: 
    id: dev_id 
    name: dev application config 

--- 
spring: 
    profiles: stage 

test-service: 
    id: stage_id 
    name: stage application config 
相關問題