O Spring Boot nos permite substituir nossos arquivos application.properties por equivalentes YAML. No entanto, pareço encontrar um obstáculo com meus testes. Se eu anotar meu TestConfiguration
(uma configuração Java simples), estou esperando um arquivo de propriedades.
Por exemplo, isso não funciona:
@PropertySource(value = "classpath:application-test.yml")
Se eu tiver isso em meu arquivo YAML:
db:
url: jdbc:oracle:thin:@pathToMyDb
username: someUser
password: fakePassword
E eu estaria alavancando esses valores com algo assim:
@Value("${db.username}") String username
No entanto, acabo com um erro assim:
Could not resolve placeholder 'db.username' in string value "${db.username}"
Como posso aproveitar os benefícios do YAML em meus testes também?
spring
spring-boot
checketts
fonte
fonte
Respostas:
Spring-boot tem um ajudante para isso, basta adicionar
no topo de suas classes de teste ou uma superclasse de teste abstrata.
Edit: Escrevi esta resposta há cinco anos. Não funciona com versões recentes do Spring Boot. Isso é o que eu faço agora (traduza o Kotlin para Java, se necessário):
é adicionado ao topo, então
para o contexto.
fonte
@SpringJUnitConfig(value = {...}, initializers = {ConfigFileApplicationContextInitializer.class})
Como foi mencionado
@PropertySource
, não carrega o arquivo yaml. Como alternativa, carregue o arquivo por conta própria e adicione as propriedades carregadas a eleEnvironment
.Implementação
ApplicationContextInitializer
:Adicione o seu inicializador ao seu teste:
fonte
YamlFileApplicationContextInitializer
classe em que a localização YAML é definida por caso de teste. Se você acha que é interessante, sinta-se à vontade para mesclá-lo com sua resposta e eu irei deletar a minha. Deixe-me saber em um comentário abaixo da minha resposta.@PropertySource
pode ser configurado porfactory
argumento. Então você pode fazer algo como:Onde
YamlPropertyLoaderFactory
está seu carregador de propriedade personalizada:Inspirado em https://stackoverflow.com/a/45882447/4527110
fonte
IllegalStateException
quando o arquivo não existe em vez do apropriadoFileNotFoundException
- então, para fazer isso funcionar@PropertySource(..., ignoreResourceNotFound = true)
, você precisará capturar e lidar com este caso:try { return new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource(), null); } catch (IllegalStateException e) { throw (IOException) e.getCause(); }
CompositePropertySource propertySource = new CompositePropertySource(name); new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource()).stream().forEach(propertySource::addPropertySource); return propertySource;
@PropertySource
suporta apenas arquivos de propriedades (é uma limitação do Spring, não do próprio Boot). Sinta-se à vontade para abrir um tíquete de solicitação de recurso no JIRA .fonte
ApplicationContextInitializer
e adicioná-lo à configuração de teste (basta usar umYamlPropertySourceLoader
para aprimorar oEnvironment
). Pessoalmente, eu preferiria que@PropertySource
suportasse esse comportamento nativamente.Outra opção é definir o
spring.config.location
meio@TestPropertySource
:fonte
@TestPropertySource(properties = {"spring.config.location=classpath:application-${test.env}.yml" })
IMO, a sua é a melhor resposta de todas.@TestPropertySource(properties = {"spring.config.location=classpath:application-config.yml,classpath:test-config.yml,..." })
@SpringBootTest
anotaçãoNo Spring Boot 1.4, você pode usar a nova
@SpringBootTest
anotação para conseguir isso mais facilmente (e para simplificar a configuração do teste de integração em geral) inicializando seus testes de integração usando o suporte do Spring Boot.Detalhes no Blog da Primavera .
Pelo que eu posso dizer, isso significa que você obtém todos os benefícios da configuração externalizada do Spring Boot, assim como no seu código de produção, incluindo a obtenção automática da configuração YAML do classpath.
Por padrão, esta anotação irá
mas você pode especificar outras classes de configuração, se necessário.
Para este caso específico, você pode combinar
@SpringBootTest
com@ActiveProfiles( "test" )
e Spring irá pegar sua configuração YAML, desde que siga os padrões de nomenclatura de inicialização normais (ou sejaapplication-test.yml
).Nota:
SpringRunner.class
é o novo nome paraSpringJUnit4ClassRunner.class
fonte
A abordagem para carregar as propriedades do yaml, IMHO, pode ser feita de duas maneiras:
uma. Você pode colocar a configuração em um local padrão -
application.yml
na raiz do classpath - normalmentesrc/main/resources
e essa propriedade yaml deve ser carregada automaticamente pelo Spring boot com o nome do caminho achatado que você mencionou.b. A segunda abordagem é um pouco mais extensa, basicamente defina uma classe para manter suas propriedades desta maneira:
Basicamente, isso quer dizer que carrega o arquivo yaml e preenche a classe DbProperties com base no elemento raiz de "db".
Agora, para usá-lo em qualquer aula, você terá que fazer o seguinte:
Qualquer uma dessas abordagens deve funcionar perfeitamente para você usando Spring-boot.
fonte
snakeyaml
é puxado como uma dependência transitiva porspring-boot-starter
, portanto, não deve haver necessidade de adicioná-lo ao seupom.xml
oubuild.gradle
, a menos que você tenha um desejo profundo de usar uma versão diferente. :)locations
não épath
, eConfigFileApplicationContextInitializer
também é necessário.Eu encontrei uma solução alternativa usando
@ActiveProfiles("test")
e adicionando um arquivo application-test.yml a src / test / resources.Acabou ficando assim:
O arquivo application-test.yml contém apenas as propriedades que desejo substituir de application.yml (que podem ser encontradas em src / main / resources).
fonte
@Value("${my.property}")
mas funciona bem se eu usarenvironment.getProperty("my.property")
.é porque você não configurou o snakeyml. Spring boot vem com o recurso @EnableAutoConfiguration. há configuração snakeyml também quando você chama essa anotação.
esta é a minha maneira:
aqui está meu teste:
fonte
Eu precisava ler algumas propriedades em meu código e isso funciona com spring-boot 1.3.0.RELEASE
fonte
Carregando arquivo yml personalizado com configuração de vários perfis no Spring Boot.
1) Adicione o bean de propriedade com SpringBootApplication inicializando da seguinte maneira
2) Configure o objeto Java pojo da seguinte maneira
3) Crie o yml personalizado (e coloque-o no caminho do recurso da seguinte forma, Nome do arquivo YML: test-service-config.yml
Por exemplo, config no arquivo yml.
fonte
Eu estava em uma situação específica em que não conseguia carregar uma classe @ConfigurationProperties devido à nomenclatura de propriedade de arquivo personalizada. No final, a única coisa que funcionou foi (obrigado @Mateusz Balbus):
fonte
Bem-vindo a usar minha biblioteca. Agora yaml , toml , hocon são suportados.
Fonte: github.com
fonte
Esta não é uma resposta à pergunta original, mas uma solução alternativa para a necessidade de ter uma configuração diferente em um teste ...
Em vez de
@PropertySource
você pode usar-Dspring.config.additional-location=classpath:application-tests.yml
.Esteja ciente, esse sufixo
tests
não significa perfil ...Nesse arquivo YAML, é possível especificar vários perfis, que podem herdar uns dos outros, leia mais aqui - Resolução de propriedades para vários perfis Spring (configuração yaml)
Em seguida, você pode especificar em seu teste, que os perfis ativos (usando
@ActiveProfiles("profile1,profile2")
) estãoprofile1,profile2
ondeprofile2
irão simplesmente substituir (alguns, não é necessário substituir todas) as propriedadesprofile1
.fonte
Eu tentei todas as questões listadas, mas todas elas não funcionam para minha tarefa: usar um arquivo yaml específico para algum teste de unidade. No meu caso, funciona assim:
fonte
Não há necessidade de adicionar como YamlPropertyLoaderFactory ou YamlFileApplicationContextInitializer. Você deve converter sua ideia. apenas como projeto de primavera comum. Você sabe, não usando a configuração Java. Apenas * .xml
Siga esses passos:
Basta adicionar applicationContext.xml como
então adicione
para o seu
ApplicationMainClass
.Isso pode ajudar a verificar seu aplicativo-test.yml
fonte