Làm thế nào để đặt biến môi trường hoặc thuộc tính hệ thống trong các bài kiểm tra mùa xuân?


93

Tôi muốn viết một số bài kiểm tra để kiểm tra cấu hình XML Spring của một WAR đã triển khai. Thật không may, một số bean yêu cầu một số biến môi trường hoặc thuộc tính hệ thống được thiết lập. Làm cách nào để tôi có thể đặt một biến môi trường trước khi khởi chạy Spring bean khi sử dụng kiểu kiểm tra thuận tiện với @ContextConfiguration?

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

Nếu tôi định cấu hình ngữ cảnh ứng dụng bằng chú thích, tôi không thấy dấu móc nơi tôi có thể làm gì đó trước khi khởi tạo ngữ cảnh mùa xuân.

Câu trả lời:


127

Bạn có thể khởi tạo thuộc tính Hệ thống trong bộ khởi tạo tĩnh:

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

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

}

Mã khởi tạo tĩnh sẽ được thực thi trước khi khởi tạo ngữ cảnh ứng dụng mùa xuân.


14
Tôi ngớ ngẩn - OK, điều đó sẽ hiệu quả. Thậm chí tốt hơn: có lẽ là một @BeforeClassphương pháp để thiết lập thuộc tính hệ thống và một @AfterClassphương pháp để loại bỏ nó cũng sẽ hoạt động và tự dọn dẹp một cách độc đáo. (Tuy nhiên, tôi chưa thử.)
Hans-Peter Störr,

1
Thử @BeforeClass - và nó làm việc tốt cho thiết lập các thuộc hệ thống trước khi các tài sản khác đã được thiết lập trong các trường hợp thử nghiệm
wbdarby

Cảm ơn vì điều đó. Tính năng tĩnh không hoạt động nhưng một phương thức nhỏ với @BeforeClass đã hoạt động!
Midhun Agnihotram

Cơ chế này không hoạt động nếu thay đổi thuộc tính tệp cấu hình Log4j2. Có vẻ như Spring vẫn đang được tải (và ghi nhật ký không chính xác) trước đoạn mã tĩnh đó.
lucasvc

86

Cách thích hợp để làm điều này, bắt đầu với Spring 4.1, là sử dụng @TestPropertySourcechú thích.

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

Xem @TestPropertySource trong tài liệu SpringJavadocs .


2
Chú thích này cũng hỗ trợ đường dẫn tệp thuộc tính.
MigDus

2
Tôi có thể chuyển đổi các nhãn mùa xuân đám mây Config khách hàng trong quá trình thử nghiệm sử dụng@TestPropertySource(properties={"spring.cloud.config.label=feature/branch"})
Marcello de Sales

4
Câu trả lời tốt, nhưng đáng buồn là không hiệu quả với tôi, khi sử dụng Spring 4.2.9, thuộc tính luôn trống. Chỉ khối tĩnh hoạt động ... Hoạt động cho các thuộc tính ứng dụng, nhưng không hoạt động cho các thuộc tính hệ thống.
Gregor

Đầu tiên tôi đã xem và thử phiên bản tĩnh (đã hoạt động), nhưng Chú thích này thậm chí còn rõ ràng hơn và thích hợp hơn nhiều (đối với tôi, vì nó cũng hoạt động như một sự quyến rũ).
BAERUS

3
Điều này cung cấp một thuộc Environmenttính, khác với "Biến môi trường".
OrangeDog

11

Người ta cũng có thể sử dụng một ApplicationContextInitializer thử nghiệm để khởi tạo thuộc tính hệ thống:

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

và sau đó định cấu hình nó trên lớp thử nghiệm ngoài các vị trí tệp cấu hình ngữ cảnh Spring:

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

Bằng cách này có thể tránh được sự trùng lặp mã nếu một thuộc tính hệ thống nhất định nên được đặt cho tất cả các bài kiểm tra đơn vị.


Điều này cũng hoạt động hoàn hảo với Spring Boot 2.x và Junit 5.x (sử dụng @SpringBootTesthoặc bất kỳ chú thích cắt lát thử nghiệm nào )
Wim Deblauwe

11

Tất cả các câu trả lời ở đây hiện chỉ nói về các thuộc tính hệ thống khác với các biến môi trường phức tạp hơn để thiết lập, đặc biệt. cho các bài kiểm tra. Rất may, lớp bên dưới có thể được sử dụng cho việc đó và tài liệu lớp có các ví dụ điển hình

EnvironmentVariables.html

Một ví dụ nhanh từ tài liệu, được sửa đổi để hoạt động với @SpringBootTest

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

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

Các quy tắc EnvironmentVariables là một phần của thư viện bên thứ ba, sử dụng phản xạ hacky để thay đổi các giá trị được lưu trong bộ nhớ cache của môi trường trong bộ nhớ JVM và thậm chí không phải các biến môi trường thực tế. Vì vậy, tôi không muốn sử dụng nó hoặc khuyên bất cứ ai làm như vậy.
Christian

4

Nếu bạn muốn các biến của mình hợp lệ cho tất cả các thử nghiệm, bạn có thể có một application.propertiestệp trong thư mục tài nguyên thử nghiệm của mình (theo mặc định src/test/resources:) trông giống như sau:

MYPROPERTY=foo

Điều này sau đó sẽ được tải và sử dụng trừ khi bạn có định nghĩa thông qua @TestPropertySourcehoặc một phương pháp tương tự - thứ tự chính xác mà các thuộc tính được tải có thể được tìm thấy trong tài liệu Spring chương 24. Cấu hình bên ngoài .


2

Bạn có thể đặt thuộc tính Hệ thống làm đối số VM.

Nếu dự án của bạn là một dự án maven thì bạn có thể thực hiện lệnh sau trong khi chạy lớp thử nghiệm:

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

Lớp kiểm tra:

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

Nếu bạn muốn chạy lớp hoặc phương thức thử nghiệm riêng lẻ trong eclipse thì:

1) Đi tới Chạy -> Chạy Cấu hình

2) Ở phía bên trái, chọn lớp Kiểm tra của bạn trong phần Junit.

3) làm như sau:

nhập mô tả hình ảnh ở đây


2

Đối với Unit Test, biến Hệ thống chưa được khởi tạo khi tôi thực hiện "mvn clean install" vì không có máy chủ nào chạy ứng dụng. Vì vậy, để thiết lập thuộc tính Hệ thống, tôi cần thực hiện điều đó trong pom.xml. Như vậy:

<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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.