วิธีตั้งค่าตัวแปรสภาพแวดล้อมหรือคุณสมบัติของระบบในการทดสอบสปริง


95

ฉันต้องการเขียนการทดสอบบางอย่างที่ตรวจสอบการกำหนดค่า XML Spring ของ WAR ที่ปรับใช้ น่าเสียดายที่ถั่วบางชนิดต้องการให้มีการตั้งค่าตัวแปรสภาพแวดล้อมหรือคุณสมบัติของระบบ ฉันจะตั้งค่าตัวแปรสภาพแวดล้อมก่อนที่ถั่วสปริงจะเริ่มต้นได้อย่างไรเมื่อใช้รูปแบบการทดสอบที่สะดวกกับ @ContextConfiguration

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

หากฉันกำหนดค่าบริบทของแอปพลิเคชันด้วยคำอธิบายประกอบฉันไม่เห็นจุดเชื่อมต่อที่ฉันสามารถทำอะไรบางอย่างได้ก่อนที่บริบทสปริงจะเริ่มต้น

คำตอบ:


127

คุณสามารถเริ่มต้นคุณสมบัติของระบบในตัวเริ่มต้นแบบคงที่:

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

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

}

รหัสเริ่มต้นแบบคงที่จะดำเนินการก่อนที่บริบทแอ็พพลิเคชันสปริงจะเริ่มต้น


14
ฉันโง่ - ตกลงมันจะได้ผล ที่ดียิ่งขึ้น: อาจเป็น@BeforeClassวิธีการตั้งค่าคุณสมบัติของระบบและ@AfterClassวิธีการลบออกก็ใช้ได้เช่นกัน (ยังไม่ได้ลอง)
Hans-Peter Störr

1
ลองใช้ @BeforeClass - และทำงานได้ดีสำหรับการตั้งค่าคุณสมบัติของระบบก่อนที่คุณสมบัติอื่น ๆ จะถูกตั้งค่าในอินสแตนซ์การทดสอบ
wbdarby

ขอบคุณสำหรับสิ่งนี้. สิ่งที่คงที่ไม่ได้ผล แต่วิธีการเล็ก ๆ กับ @BeforeClass ใช้งานได้!
Midhun Agnihotram

กลไกนี้ไม่ทำงานหากเปลี่ยนคุณสมบัติไฟล์คอนฟิกูเรชัน Log4j2 ดูเหมือนว่า Spring กำลังโหลดอยู่ (และบันทึกไม่ถูกต้อง) ก่อนชิ้นส่วนคงที่ของโค้ด
lucasvc

87

วิธีที่ถูกต้องในการทำเช่นนี้โดยเริ่มจาก Spring 4.1 คือการใช้@TestPropertySourceคำอธิบายประกอบ

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

ดู @TestPropertySource ในเอกสารฤดูใบไม้ผลิและJavadocs


2
คำอธิบายประกอบนี้ยังสนับสนุนเส้นทางไฟล์คุณสมบัติ
MigDus

2
ฉันสามารถเปลี่ยนป้ายกำกับ Spring Cloud Config Client ระหว่างการทดสอบโดยใช้@TestPropertySource(properties={"spring.cloud.config.label=feature/branch"})
Marcello de Sales

5
คำตอบที่ดี แต่น่าเสียดายที่ไม่ได้ผลสำหรับฉันเมื่อใช้ Spring 4.2.9 คุณสมบัติว่างเปล่าตลอดเวลา เฉพาะบล็อกแบบคงที่เท่านั้นที่ทำงานได้ ... ทำงานสำหรับคุณสมบัติของแอ็พพลิเคชัน แต่ไม่ใช่สำหรับคุณสมบัติของระบบ
Gregor

ก่อนอื่นฉันเห็นและลองใช้เวอร์ชันคงที่ (ซึ่งใช้งานได้) แต่คำอธิบายประกอบนี้สะอาดกว่าและเป็นที่ต้องการมากกว่า (สำหรับฉันเพราะมันใช้งานได้เหมือนมีเสน่ห์)
BAERUS

4
สิ่งนี้ให้Environmentคุณสมบัติซึ่งแตกต่างจาก "ตัวแปรสภาพแวดล้อม"
OrangeDog

11

คุณยังสามารถใช้ ApplicationContextInitializer ทดสอบเพื่อเตรียมใช้งานคุณสมบัติของระบบ:

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

จากนั้นกำหนดค่าในคลาสทดสอบนอกเหนือจากตำแหน่งไฟล์กำหนดค่าบริบท Spring:

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

วิธีนี้สามารถหลีกเลี่ยงการทำซ้ำรหัสได้หากควรตั้งค่าคุณสมบัติของระบบสำหรับการทดสอบหน่วยทั้งหมด


สิ่งนี้ยังทำงานได้อย่างสมบูรณ์แบบกับ Spring Boot 2.x และ Junit 5.x (โดยใช้@SpringBootTestหรือคำอธิบายประกอบการทดสอบการแบ่งส่วนข้อมูลใด ๆ)
Wim Deblauwe

11

คำตอบทั้งหมดที่นี่พูดถึงคุณสมบัติของระบบซึ่งแตกต่างจากตัวแปรสภาพแวดล้อมที่ซับซ้อนกว่าในการตั้งค่าโดยเฉพาะ สำหรับการทดสอบ โชคดีที่สามารถใช้ชั้นเรียนด้านล่างนี้ได้และเอกสารของชั้นเรียนมีตัวอย่างที่ดี

EnvironmentVariables.html

ตัวอย่างสั้น ๆ จากเอกสารที่แก้ไขให้ทำงานกับ @SpringBootTest

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

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

กฎ EnvironmentVariables เป็นส่วนหนึ่งของไลบรารีของบุคคลที่สามใช้การสะท้อนแบบแฮ็กกี้เพื่อเปลี่ยนค่าแคชของสภาพแวดล้อมในหน่วยความจำ JVM และไม่แม้แต่ตัวแปรสภาพแวดล้อมจริง ดังนั้นฉันไม่ต้องการใช้หรือแนะนำให้ใครทำเช่นนั้น
Christian

4

หากคุณต้องการให้ตัวแปรของคุณถูกต้องสำหรับการทดสอบทั้งหมดคุณสามารถมีapplication.propertiesไฟล์ในไดเร็กทอรีทรัพยากรการทดสอบของคุณ (โดยค่าเริ่มต้น :) src/test/resourcesซึ่งจะมีลักษณะดังนี้:

MYPROPERTY=foo

นี้จะถูกโหลดและใช้จนกว่าคุณจะมีความหมายผ่านทาง@TestPropertySourceหรือวิธีการที่คล้ายกัน - คำสั่งซื้อที่แน่นอนในคุณสมบัติที่จะถูกโหลดสามารถพบได้ในฤดูใบไม้ผลิเอกสารบทที่24. การกำหนดค่าภายนอก


2

คุณสามารถตั้งค่าคุณสมบัติของระบบเป็นอาร์กิวเมนต์ VM

หากโปรเจ็กต์ของคุณเป็นโปรเจ็กต์ maven คุณสามารถรันคำสั่งต่อไปนี้ในขณะที่รันคลาสทดสอบ:

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

ชั้นทดสอบ:

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

หากคุณต้องการรันคลาสทดสอบแต่ละคลาสหรือเมธอดใน eclipse แล้ว:

1) ไปที่ Run -> Run Configuration

2) ทางด้านซ้ายให้เลือกชั้นเรียนทดสอบของคุณภายใต้ส่วน Junit

3) ทำสิ่งต่อไปนี้:

ป้อนคำอธิบายภาพที่นี่


2

สำหรับการทดสอบหน่วยตัวแปรระบบยังไม่ได้สร้างอินสแตนซ์เมื่อฉันทำการ "mvn clean install" เนื่องจากไม่มีเซิร์ฟเวอร์ที่เรียกใช้แอปพลิเคชัน ดังนั้นในการตั้งค่าคุณสมบัติของระบบฉันต้องทำใน pom.xml ชอบมาก:

<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>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.