2012-11-13 53 views
27

Tôi đã có một ứng dụng web mà tôi có vấn đề điển hình là nó yêu cầu các tệp cấu hình khác nhau cho các môi trường khác nhau. Một số cấu hình được đặt trong máy chủ ứng dụng dưới dạng nguồn dữ liệu JNDI, tuy nhiên một số cấu hình vẫn nằm trong các tệp thuộc tính.Cấu hình mùa xuân và Thử nghiệm

Tôi muốn sử dụng tính năng Cấu hình mùa xuân.

Vấn đề của tôi là tôi không chạy thử nghiệm.

context.xml:

<context:property-placeholder 
    location="classpath:META-INF/spring/config_${spring.profiles.active}.properties"/> 

TestCase:

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({ 
    TestPreperationExecutionListener.class 
    }) 
@Transactional 
@ActiveProfiles(profiles = "localtest") 
@ContextConfiguration(locations = { 
    "classpath:context.xml" }) 
public class TestContext { 

    @Test 
    public void testContext(){ 

    } 
} 

Vấn đề dường như là biến cho tải hồ sơ không được giải quyết:

Caused by: java.io.FileNotFoundException: class path resource [META-INF/spring/config_${spring.profiles.active}.properties] cannot be opened because it does not exist 
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:157) 
at org.springframework.core.io.support.PropertiesLoaderSupport.loadProperties(PropertiesLoaderSupport.java:181) 
at org.springframework.core.io.support.PropertiesLoaderSupport.mergeProperties(PropertiesLoaderSupport.java:161) 
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.postProcessBeanFactory(PropertySourcesPlaceholderConfigurer.java:138) 
... 31 more 

hiện nay nên đặt cấu hình bằng chú thích @ActiveProfile. Vì đó là một testcase, tôi sẽ không thể sử dụng số web.xml. Nếu có thể, tôi cũng muốn tránh các tùy chọn thời gian chạy. Các thử nghiệm nên chạy như là (nếu có thể).

Làm cách nào để kích hoạt đúng cấu hình? Có thể đặt cấu hình bằng tệp ngữ cảnh không? Tôi có thể khai báo biến trong tệp test-context.xml thực sự đang gọi ngữ cảnh bình thường không?

Trả lời

23

Tôi có thể khuyên bạn nên làm theo cách này, xác định thử nghiệm của bạn như thế này:

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({ 
    TestPreperationExecutionListener.class 
    }) 
@Transactional 
@ActiveProfiles(profiles = "localtest") 
@ContextConfiguration 
public class TestContext { 

    @Test 
    public void testContext(){ 

    } 

    @Configuration 
    @PropertySource("classpath:/myprops.properties") 
    @ImportResource({"classpath:context.xml" }) 
    public static class MyContextConfiguration{ 

    } 
} 

với các nội dung sau đây trong tập tin myprops.properties:

spring.profiles.active=localtest 

Với điều này tập tin thuộc tính thứ hai của bạn sẽ nhận được đã giải quyết:

META-INF/spring/config_${spring.profiles.active}.properties 
+1

Cảm ơn. Đã tìm ra một cải tiến được thêm vào bên dưới. –

+0

Cách tiếp cận này không sạch sẽ, bạn sẽ phải chuyển đến tệp thuộc tính nơi thay đổi giá trị hồ sơ hiện hoạt. – codebusta

5

Nhìn vào câu trả lời của Biju Tôi đã tìm được giải pháp làm việc.

tôi đã tạo thêm ngữ cảnh tập tin test-context.xml:

<context:property-placeholder location="classpath:config/spring-test.properties"/> 

Chứa hồ sơ cá nhân:

spring.profiles.active=localtest 

Và tải thử nghiệm với:

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({ 
    TestPreperationExecutionListener.class 
    }) 
@Transactional 
@ActiveProfiles(profiles = "localtest") 
@ContextConfiguration(locations = { 
    "classpath:config/test-context.xml" }) 
public class TestContext { 

    @Test 
    public void testContext(){ 

    } 
} 

Điều này tiết kiệm một số công việc khi tạo nhiều trường hợp thử nghiệm.

+0

Vì vậy, mỗi khi bạn muốn chạy thử nghiệm, bạn sẽ phải đi đến test-context.xml và thay đổi đường dẫn tệp thuộc tính, nếu muốn tải thuộc tính khác? Nó mâu thuẫn với ý tưởng của hồ sơ mùa xuân. Hãy xem giải pháp của tôi trong trường hợp này. – codebusta

+0

@CodeBusta Không, đó là một test.xml context chỉ dành cho thử nghiệm tải ngữ cảnh thông thường. –

2

Cách tiếp cận tốt nhất ở đây là để loại bỏ @ActiveProfiles chú thích và làm như sau:

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({ 
    TestPreperationExecutionListener.class 
    }) 
@Transactional 
@ContextConfiguration(locations = { 
    "classpath:config/test-context.xml" }) 
public class TestContext { 

    @BeforeClass 
    public static void setSystemProperty() { 
     Properties properties = System.getProperties(); 
     properties.setProperty("spring.profiles.active", "localtest"); 
    } 

    @AfterClass 
    public static void setSystemProperty() { 
     System.clearProperty("spring.profiles.active"); 
    } 

    @Test 
    public void testContext(){ 

    } 
} 

Và thử context.xml của bạn nên có những điều sau đây:

<context:property-placeholder 
    location="classpath:META-INF/spring/config_${spring.profiles.active}.properties"/> 
+2

Sử dụng các thuộc tính tĩnh mà không làm sạch chúng trong @AfterClass có thể dẫn đến sự cố nghiêm trọng, khó khăn đối với analyser. –

+0

Bạn có đề xuất nào khác không? Nếu bạn có giải pháp tốt hơn, bạn có thể đặt nó ở đây. – codebusta

+2

Vâng, như tôi đã nói: ít nhất là làm sạch các thuộc tính thông qua System.clearProperty() trong một phương pháp AfterClass. Hoặc sử dụng một số quy tắc như https://stefanbirkner.github.io/system-rules/ –

Các vấn đề liên quan