Come impostare la variabile di ambiente o la proprietà di sistema nei test di primavera?


93

Vorrei scrivere alcuni test che controllano la configurazione XML Spring di un WAR distribuito. Purtroppo alcuni bean richiedono l'impostazione di alcune variabili d'ambiente o proprietà di sistema. Come posso impostare una variabile di ambiente prima che i bean spring vengano inizializzati quando si utilizza il comodo stile di test con @ContextConfiguration?

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:whereever/context.xml")
public class TestWarSpringContext { ... }

Se configuro il contesto dell'applicazione con annotazioni, non vedo un hook in cui posso fare qualcosa prima che il contesto della molla sia inizializzato.

Risposte:


127

Puoi inizializzare la proprietà System in un inizializzatore statico:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:whereever/context.xml")
public class TestWarSpringContext {

    static {
        System.setProperty("myproperty", "foo");
    }

}

Il codice dell'inizializzatore statico verrà eseguito prima dell'inizializzazione del contesto dell'applicazione Spring.


14
Sciocco io - OK, funzionerebbe. Ancora meglio: probabilmente funzionerebbe anche un @BeforeClassmetodo per impostare la proprietà di sistema e un @AfterClassmetodo per rimuoverla, e si ripulirebbe bene dopo se stesso. (Non l'ho provato, però.)
Hans-Peter Störr

1
Ho provato @BeforeClass - e ha funzionato bene per impostare le proprietà di sistema prima che altre proprietà fossero impostate nell'istanza di test
wbdarby

Grazie per questo. La cosa statica non ha funzionato ma un piccolo metodo con @BeforeClass ha funzionato!
Midhun Agnihotram

Questo meccanismo non funziona se si modifica la proprietà del file di configurazione Log4j2. Sembra che Spring venga comunque caricato (e quindi loggato in modo errato) prima di quella parte statica di codice.
lucasvc

86

Il modo giusto per farlo, a partire da Spring 4.1, è usare @TestPropertySourceun'annotazione.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:whereever/context.xml")
@TestPropertySource(properties = {"myproperty = foo"})
public class TestWarSpringContext {
    ...    
}

Vedere @TestPropertySource nella documentazione di primavera e in Javadoc .


2
Questa annotazione supporta anche un percorso del file delle proprietà.
MigDus

2
Potrei cambiare l'etichetta Spring Cloud Config Client durante i test usando@TestPropertySource(properties={"spring.cloud.config.label=feature/branch"})
Marcello de Sales

4
Buona risposta, ma purtroppo non ha funzionato per me, utilizzando Spring 4.2.9, la proprietà era sempre vuota. Solo il blocco statico ha funzionato ... Ha funzionato per le proprietà dell'applicazione, ma non per le proprietà di sistema.
Gregor

Per prima cosa ho visto e provato la versione statica (che ha funzionato), ma questa annotazione è ancora più pulita e molto più preferibile (per me, poiché funziona anche come un incantesimo).
BAERUS

3
Ciò fornisce una Environmentproprietà, che è diversa da una "Variabile d'ambiente".
OrangeDog

11

Si può anche usare un ApplicationContextInitializer di prova per inizializzare una proprietà di sistema:

public class TestApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
{
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext)
    {
        System.setProperty("myproperty", "value");
    }
}

e quindi configurarlo sulla classe di test oltre alle posizioni dei file di configurazione del contesto Spring:

@ContextConfiguration(initializers = TestApplicationContextInitializer.class, locations = "classpath:whereever/context.xml", ...)
@RunWith(SpringJUnit4ClassRunner.class)
public class SomeTest
{
...
}

In questo modo è possibile evitare la duplicazione del codice se una determinata proprietà di sistema deve essere impostata per tutti gli unit test.


Funziona perfettamente anche con Spring Boot 2.xe Junit 5.x (utilizzando @SpringBootTesto una qualsiasi delle annotazioni di slicing di prova )
Wim Deblauwe

10

Tutte le risposte qui attualmente parlano solo delle proprietà di sistema che sono diverse dalle variabili di ambiente che sono più complesse da impostare, specialmente. per i test. Per fortuna, la classe sottostante può essere utilizzata per questo e i documenti di classe hanno buoni esempi

EnvironmentVariables.html

Un rapido esempio dalla documentazione, modificato per funzionare con @SpringBootTest

@SpringBootTest
public class EnvironmentVariablesTest {
   @ClassRule
   public final EnvironmentVariables environmentVariables = new EnvironmentVariables().set("name", "value");

   @Test
   public void test() {
     assertEquals("value", System.getenv("name"));
   }
 }

Le regole EnvironmentVariables fanno parte di una libreria di terze parti, utilizza la riflessione hacky per modificare i valori memorizzati nella cache dell'ambiente nella memoria JVM e non include nemmeno le variabili di ambiente effettive. Quindi, non vorrei usarlo o raccomandare a nessuno di farlo.
Christian

4

Se vuoi che le tue variabili siano valide per tutti i test, puoi avere un application.propertiesfile nella directory delle risorse di test (per impostazione predefinita :) src/test/resourcesche avrà un aspetto simile a questo:

MYPROPERTY=foo

Questo verrà quindi caricato e utilizzato a meno che non si disponga di definizioni tramite @TestPropertySourceo un metodo simile: l'ordine esatto in cui vengono caricate le proprietà può essere trovato nel capitolo 24 della documentazione di Spring . Configurazione esterna .


2

È possibile impostare le proprietà di sistema come argomenti della macchina virtuale.

Se il tuo progetto è un progetto maven, puoi eseguire il seguente comando durante l'esecuzione della classe di test:

mvn test -Dapp.url="https://stackoverflow.com"

Classe di prova:

public class AppTest  {
@Test
public void testUrl() {
    System.out.println(System.getProperty("app.url"));
    }
}

Se desideri eseguire una singola classe o metodo di test in eclipse, allora:

1) Vai a Esegui -> Esegui configurazione

2) Sul lato sinistro seleziona la tua classe di test nella sezione Junit.

3) procedi come segue:

inserisci qui la descrizione dell'immagine


2

Per i test unitari, la variabile di sistema non viene ancora creata quando eseguo "mvn clean install" perché non è presente alcun server che esegue l'applicazione. Quindi, per impostare le proprietà di sistema, devo farlo in pom.xml. Così:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.21.0</version>
    <configuration>
        <systemPropertyVariables>
            <propertyName>propertyValue</propertyName>
            <MY_ENV_VAR>newValue</MY_ENV_VAR>
            <ENV_TARGET>olqa</ENV_TARGET>
            <buildDirectory>${project.build.directory}</buildDirectory>
        </systemPropertyVariables>
    </configuration>
</plugin>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.