2012-10-05 33 views
5

Vì lý do nào đó, chú thích @Value không được đưa vào lớp mà tôi đang sử dụng làm cơ sở cho các lớp thử nghiệm khác. Tôi mới làm quen với Spring và kiến ​​thức về Java của tôi chưa phải là tốt nhất. Tôi chắc chắn điều này sẽ rõ ràng hơn đối với một người có nhiều kinh nghiệm hơn, nhưng tôi không thể hiểu được điều này.Chú thích @Value trong lớp kiểm tra cơ sở không tiêm các giá trị từ tệp thuộc tính

Nếu tôi nhận xét phương thức setDbProperties(), các trường được điền, nhưng chỉ với các chú thích @Value, tôi nhận được giá trị rỗng trong các trường.

Đây là lớp cơ sở thử nghiệm của tôi:

package com.blah; 

import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.util.Properties; 

import org.dbunit.DBTestCase; 
import org.dbunit.PropertiesBasedJdbcDatabaseTester; 
import org.dbunit.dataset.IDataSet; 
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; 
import org.dbunit.operation.DatabaseOperation; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.test.context.ActiveProfiles; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { 
     "classpath:/WEB-INF/application-context.xml", 
     "classpath:/WEB-INF/application-context-test.xml" }) 
@ActiveProfiles("test") 
public abstract class BaseDbTestCase extends DBTestCase { 

    @Value("${test.db.connection.url}") 
    private String connectionUrl; 

    @Value("${test.db.driver.class}") 
    private String driverClass; 

    @Value("${test.db.username}") 
    private String dbUserName; 

    @Value("${test.db.password}") 
    private String dbPassword; 

    @Value("${test.db.datasource.path}") 
    private String dataSource; 

    public BaseDbTestCase(String name) throws IOException { 

     super(name); 

     // setDbProperties(); 

     System.setProperty(
       PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, 
       driverClass); 
     System.setProperty(
       PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, 
       connectionUrl); 
     System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, 
       dbUserName); 
     System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, 
       dbPassword); 
    } 

    @After 
    public void after() throws Exception { 
     DatabaseOperation.DELETE_ALL.execute(getConnection(), getDataSet()); 
    } 

    @Override 
    protected IDataSet getDataSet() throws Exception { 
     return new FlatXmlDataSetBuilder() 
       .build(new FileInputStream(dataSource)); 
    } 

    private void setDbProperties() throws IOException, FileNotFoundException { 

     Properties properties = new Properties(); 

     properties.load(new FileInputStream(
       "src/main/java/resources/application.properties")); 

     connectionUrl = properties.getProperty("test.db.connection.url"); 
     driverClass = properties.getProperty("test.db.driver.class"); 
     dbUserName = properties.getProperty("test.db.username"); 
     dbPassword = properties.getProperty("test.db.password"); 
     dataSource = properties.getProperty("test.db.datasource.path"); 
    } 

    @Override 
    protected DatabaseOperation getSetUpOperation() throws Exception { 
     return DatabaseOperation.REFRESH; 
    } 

    @Override 
    protected DatabaseOperation getTearDownOperation() throws Exception { 
     return DatabaseOperation.NONE; 
    } 

    @Before 
    public void init() throws Exception { 
     DatabaseOperation.REFRESH.execute(getConnection(), getDataSet()); 
    } 

} 

Như bạn có thể thấy, mùa xuân khác (và phi Spring) chú thích được làm việc trong lớp này.

Tôi có <context:property-placeholder location="classpath:/resources/application.properties" /> trong ngữ cảnh ứng dụng của mình.

Ngoài ra, chú thích @Value đang hoạt động tốt trong các lớp mở rộng lớp BaseDbTestCase.

TIA

Cập nhật: Sau khi @ đề nghị Biju để di chuyển các thiết lập của các thuộc tính hệ thống với phương pháp init() (chú thích với @Before), tôi bây giờ nhận được stack trace sau. Dựa trên gỡ lỗi, nó không có vẻ để vượt qua các nhà xây dựng trước khi ném lỗi.

org.dbunit.assertion.DbAssertionFailedError: driverClass is null 
    at org.dbunit.assertion.DefaultFailureHandler$DefaultFailureFactory.createFailure(DefaultFailureHandler.java:265) 
    at org.dbunit.assertion.DefaultFailureHandler.createFailure(DefaultFailureHandler.java:110) 
    at org.dbunit.assertion.SimpleAssert.fail(SimpleAssert.java:90) 
    at org.dbunit.assertion.SimpleAssert.assertTrue(SimpleAssert.java:77) 
    at org.dbunit.assertion.SimpleAssert.assertNotNullNorEmpty(SimpleAssert.java:61) 
    at org.dbunit.JdbcDatabaseTester.<init>(JdbcDatabaseTester.java:103) 
    at org.dbunit.PropertiesBasedJdbcDatabaseTester.<init>(PropertiesBasedJdbcDatabaseTester.java:68) 
    at org.dbunit.DBTestCase.newDatabaseTester(DBTestCase.java:70) 
    at org.dbunit.DatabaseTestCase.getDatabaseTester(DatabaseTestCase.java:109) 
    at org.dbunit.DatabaseTestCase.setUp(DatabaseTestCase.java:151) 
    at junit.framework.TestCase.runBare(TestCase.java:132) 
    at junit.framework.TestResult$1.protect(TestResult.java:110) 
    at junit.framework.TestResult.runProtected(TestResult.java:128) 
    at junit.framework.TestResult.run(TestResult.java:113) 
    at junit.framework.TestCase.run(TestCase.java:124) 
    at junit.framework.TestSuite.runTest(TestSuite.java:243) 
    at junit.framework.TestSuite.run(TestSuite.java:238) 
    at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
+0

Tôi có cùng một vấn đề. Bạn có thể tìm thấy một giải pháp? –

Trả lời

1

Lý do tôi nghĩ là bởi vì khi bạn lấy được một trường hợp thử nghiệm mới dựa trên của bạn BaseDbTestCase các @ContextConfiguration trong BaseDbTestCase là không thực sự rõ ràng trong trường hợp kiểm tra nguồn gốc - các @ContextConfiguration phải được trên trường hợp thử nghiệm cuối cùng của bạn.

Cập nhật:

Những gì tôi đã đưa ở trên là không đúng, tôi đã thử nghiệm một lần và nó trông giống như @ContextConfiguration@RunWith ngay cả trong lớp cơ sở là đủ và nó sẽ tiêm nhiễm một cách chính xác trong @Value trường trong cơ sở lớp học. Bây giờ vấn đề bạn đang gặp là vì bạn đang mong đợi các biến có sẵn trong hàm tạo - chúng sẽ không được, bởi vì @Value được giải quyết SAU trường hợp được tạo ra - vì vậy trong trường hợp của bạn vì bạn đang mong đợi nó để có mặt trong constructor nó sẽ thất bại. Thay vào đó, bạn có thể đặt thuộc tính ở phương thức được chú thích là @Before của Junit

+0

Dường như '@ ContextConfiguration' là không quan trọng. Dù bằng cách nào, các trường của tôi được chú thích bằng '@ Value' không được điền. – Luke

+0

Đã thêm câu trả lời cập nhật - lý do là bạn đang mong đợi giá trị được phản ánh trong hàm tạo trong khi '@ Value' được giải quyết bài đăng xây dựng. –

+0

Vì lý do nào đó, trong trường hợp đặc biệt này, việc thiết lập các thuộc tính hệ thống phải xảy ra trong hàm tạo, nếu không tôi sẽ không bao giờ vượt qua hàm tạo. Thay vào đó, tôi nhận được dấu vết ngăn xếp mà tôi đã cập nhật câu hỏi của mình. Bất kỳ ý tưởng? – Luke

0

Có lớp bê tông mở rộng BaseDbTestCase và đặt @ContextConfiguration trong lớp bê tông. Làm cho các lớp thử nghiệm khác của bạn mở rộng lớp bê tông này.

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