2015-04-16 16 views
74

Ho un'applicazione Spring-Boot in cui le proprietà predefinite sono impostate in un file application.properties nel classpath (src/main/resources/application.properties).Sovrascrivi impostazioni predefinite dell'applicazione Spring-Boot application.properties in Junit Test

vorrei ignorare alcune impostazioni predefinite nel mio test JUnit con proprietà dichiarate in un file test.properties (src/test/risorse/test.properties)

ho quando arrivavano avere una classe di configurazione dedicato per i miei test JUnit, per esempio

package foo.bar.test; 

import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Import; 

@Configuration 
@Import(CoreConfig.class) 
@EnableAutoConfiguration 
public class TestConfig { 

} 

ho pensato che l'utilizzo @PropertySource("classpath:test.properties") nella classe TestConfig farebbe il trucco, ma queste proprietà non sovrascriverà le impostazioni application.properties (vedi Primavera-Boot di riferimento Doc - 23. Externalized Configuration).

Quindi ho provato a utilizzare -Dspring.config.location=classpath:test.properties durante il richiamo del test. Ciò ha avuto successo, ma non voglio impostare questa proprietà di sistema per ogni esecuzione del test. Così l'ho inserito nel codice

@Configuration 
@Import(CoreConfig.class) 
@EnableAutoConfiguration 
public class TestConfig { 

    static { 
    System.setProperty("spring.config.location", "classpath:test.properties"); 
    } 

} 

che purtroppo non è stato ancora un successo.

Ci deve essere una soluzione semplice su come ignorare le impostazioni di application.properties nei test di JUnit con test.properties che devo aver ignorato.

risposta

142

È possibile utilizzare @TestPropertySource per sovrascrivere i valori in application.properties. Dalla sua javadoc:

fonti proprietà in prova possono essere utilizzati per sostituire selettivamente proprietà definite nel sistema e proprietà applicazione fonti

Ad esempio:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = ExampleApplication.class) 
@TestPropertySource(locations="classpath:test.properties") 
public class ExampleApplicationTests { 

} 
+1

Questo è tutto. Grazie. Sfortunatamente non funziona se usato su ExampleApplication.class, quindi devo impostarlo su ogni classe di test. È giusto? – FrVaBe

+1

Deve andare da qualche parte nella gerarchia della classe di test, ad esempio è possibile utilizzare una superclasse comune per configurarla su un numero di classi di test diverse. –

+0

Sì, sarebbe un vero problema, ma poiché '@ PropertySource' è supportato nelle classi' @ Configuration' perché non anche '@ TestPropertySource' ;-) Comunque - come previsto, il framework non mi deluderà e ti ringrazio ancora per rispondere alla domanda. – FrVaBe

37

È possibile anche utilizzare meta-annotations esternare la configurazione. Per esempio:

@RunWith(SpringJUnit4ClassRunner.class) 
@DefaultTestAnnotations 
public class ExampleApplicationTests { 
    ... 
} 

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
@SpringApplicationConfiguration(classes = ExampleApplication.class) 
@TestPropertySource(locations="classpath:test.properties") 
public @interface DefaultTestAnnotations { } 
+0

Grazie per aver condiviso questo approccio. Non ero a conoscenza delle meta-annotazioni finora. Così tante cose belle devo ancora scoprire ... – FrVaBe

0

Altrimenti si potrebbe cambiare il nome della proprietà di configurazione di default, l'impostazione della proprietà spring.config.name=test e poi avere delle risorse di classe-path src/test/test.properties nostra istanza nativo di org.springframework.boot.SpringApplication sarà automaticamente configurato da questo test.properties separati, ignorando le proprietà dell'applicazione;

Vantaggio: autoconfigurazione dei test;

Svantaggio: esporre la proprietà "spring.config.name" in C.I. strato

ref: http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

spring.config.name = Nome del file di configurazione #

+2

Ignorare 'application.properties' non è un'opzione per me perché voglio solo sovrascrivere _some_ dei valori di configurazione originali nel test. – FrVaBe

12

Primavera avvio carica automaticamente src/test/resources/application.properties, se si utilizzano seguenti annotazioni

@RunWith(SpringRunner.class) 
@SpringBootTest 

Quindi, rinominare test.properties a application.properties di utilizzare la configurazione automatica.

Se voi * solo * necessità di caricare il file delle proprietà (nell'ambiente) uso può anche utilizzare la seguente, come ha spiegato here

@RunWith(SpringRunner.class) 
@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class) 

[Aggiornamento: Sostituzione di alcune proprietà per il test]

  1. Aggiungi src/main/resources/application-test.properties.
  2. Annota la classe di prova con @ActiveProfile("test").

Questo carica application.properties e poiapplication-test.properties proprietà nel contesto applicativo per il caso di test, secondo regole definite here.

Demo - https://github.com/mohnish82/so-spring-boot-testprops

+0

Non sono sicuro se sia una buona idea avere due file 'application.properties' sul classpath (uno in' src/main/resources' e uno in 'src/test/resources'). Chi garantisce che entrambi saranno presi e quale sarà preso per primo? – FrVaBe

+0

@FrVaBe Spring lo garantirà! Le proprietà principali del profilo sono sempre caricate. Quindi durante la fase di test, vengono caricate le proprietà di test, aggiungendo/sovrascrivendo proprietà nuove/esistenti. Se non ti piace conservare due file con lo stesso nome, puoi aggiungere 'application-test.properties' in' src/main/resources' e specificare 'test' come profilo attivo nel caso di test. – Mohnish

+0

Spring non dà una garanzia. Lo strumento di compilazione utilizzerà le risorse di test a favore delle risorse principali durante i test. Ma nel caso di un'applicazione di prova.proprietà, le principali proprietà dell'applicazione verranno ignorate.Questo non è quello che voglio perché quello principale contiene diversi valori predefiniti utili e devo solo sovrascrivere alcuni di essi durante il test (e non voglio duplicare l'intero file nella sezione test). Vedi [qui] (https://twitter.com/snicoll/status/887224501871751168). – FrVaBe

Problemi correlati