Bagaimana cara mengatur variabel lingkungan atau properti sistem dalam pengujian musim semi?

95

Saya ingin menulis beberapa pengujian yang memeriksa konfigurasi XML Spring dari WAR yang diterapkan. Sayangnya beberapa kacang membutuhkan beberapa variabel lingkungan atau properti sistem yang ditetapkan. Bagaimana cara menyetel variabel lingkungan sebelum kacang pegas diinisialisasi saat menggunakan gaya pengujian praktis dengan @ContextConfiguration?

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

Jika saya mengonfigurasi konteks aplikasi dengan anotasi, saya tidak melihat kait di mana saya dapat melakukan sesuatu sebelum konteks pegas diinisialisasi.

Hans-Peter Störr
sumber

Jawaban:

127

Anda dapat menginisialisasi properti System di penginisialisasi statis:

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

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

}

Kode penginisialisasi statis akan dijalankan sebelum konteks aplikasi pegas diinisialisasi.

Jimmy Praet
sumber
14
Saya konyol - OK, itu akan berhasil. Lebih baik lagi: mungkin @BeforeClassmetode untuk menyetel properti sistem dan @AfterClassmetode untuk menghapusnya juga akan berfungsi, dan membersihkannya dengan baik setelahnya. (Namun, tidak mencobanya.)
Hans-Peter Störr
1
Mencoba @BeforeClass - dan berfungsi dengan baik untuk menyetel properti sistem sebelum properti lain disetel dalam instance pengujian
wbdarby
Terima kasih untuk ini. Hal statis tidak berfungsi tetapi metode kecil dengan @BeforeClass berhasil!
Midhun Agnihotram
Mekanisme ini tidak bekerja jika mengubah properti file konfigurasi Log4j2. Tampaknya Spring tetap dimuat (dan karena itu logging salah) sebelum potongan kode statis itu.
lucasvc
87

Cara yang benar untuk melakukannya, dimulai dengan Spring 4.1, adalah dengan menggunakan @TestPropertySourceanotasi.

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

Lihat @TestPropertySource di dokumen Spring dan Javadocs .

Raman
sumber
2
Anotasi ini juga mendukung jalur file properti.
MigDus
2
Saya dapat mengganti label Klien Spring Cloud Config selama pengujian menggunakan@TestPropertySource(properties={"spring.cloud.config.label=feature/branch"})
Marcello de Sales
5
Jawaban yang bagus, tapi sayangnya tidak berhasil untuk saya, menggunakan Spring 4.2.9, properti selalu kosong. Hanya blok statis yang bekerja ... Berfungsi untuk properti aplikasi, tetapi tidak untuk properti sistem.
Gregor
Pertama saya melihat dan mencoba versi statis (yang berhasil), tetapi Anotasi ini bahkan lebih bersih dan lebih disukai (bagi saya, karena ini juga berfungsi seperti pesona).
BAERUS
4
Ini memberikan Environmentproperti, yang berbeda dengan "variabel Lingkungan".
OrangeDog
11

Anda juga dapat menggunakan pengujian ApplicationContextInitializer untuk menginisialisasi properti sistem:

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

dan kemudian konfigurasikan di kelas pengujian selain lokasi file konfigurasi konteks musim semi:

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

Duplikasi kode dengan cara ini dapat dihindari jika properti sistem tertentu harus disetel untuk semua pengujian unit.

anre
sumber
Ini juga berfungsi sempurna dengan Spring Boot 2.x dan Junit 5.x (menggunakan @SpringBootTestatau salah satu anotasi pemotongan uji )
Wim Deblauwe
11

Semua jawaban di sini saat ini hanya berbicara tentang properti sistem yang berbeda dari variabel lingkungan yang lebih kompleks untuk ditetapkan, esp. untuk ujian. Untungnya, kelas di bawah ini dapat digunakan untuk itu dan dokumen kelas memiliki contoh yang bagus

EnvironmentVariables.html

Contoh singkat dari dokumen, dimodifikasi untuk bekerja dengan @SpringBootTest

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

   @Test
   public void test() {
     assertEquals("value", System.getenv("name"));
   }
 }
Harish Gokavarapu
sumber
Aturan EnvironmentVariables adalah bagian dari pustaka pihak ketiga, menggunakan refleksi hacky untuk mengubah nilai cache dari lingkungan dalam memori JVM dan bahkan tidak variabel lingkungan sebenarnya. Jadi, saya tidak ingin menggunakannya atau merekomendasikan siapa pun untuk melakukannya.
Christian
4

Jika Anda ingin variabel Anda valid untuk semua pengujian, Anda dapat memiliki application.propertiesfile di direktori sumber daya pengujian (secara default :) src/test/resourcesyang akan terlihat seperti ini:

MYPROPERTY=foo

Ini kemudian akan dimuat dan digunakan kecuali Anda memiliki definisi melalui @TestPropertySourceatau metode serupa - urutan persis di mana properti dimuat dapat ditemukan di dokumentasi Spring bab 24. Konfigurasi Eksternal .

blalasaadri
sumber
2

Anda dapat mengatur properti Sistem sebagai argumen VM.

Jika project Anda adalah project maven, Anda dapat menjalankan perintah berikut saat menjalankan kelas pengujian:

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

Kelas tes:

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

Jika Anda ingin menjalankan kelas atau metode pengujian individu dalam gerhana maka:

1) Buka Jalankan -> Jalankan Konfigurasi

2) Di sisi kiri pilih kelas Tes Anda di bawah bagian Junit.

3) lakukan hal berikut:

masukkan deskripsi gambar di sini

Joby Wilson Mathews
sumber
2

Untuk Pengujian Unit, variabel Sistem belum dibuat saat saya melakukan "mvn clean install" karena tidak ada server yang menjalankan aplikasi. Jadi untuk mengatur properti Sistem, saya perlu melakukannya di pom.xml. Seperti:

<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>
Gen
sumber