运行测试用例时,Spring依赖注入为null

时间:2012-08-02 11:53:09

标签: java spring dependency-injection junit

我正在使用Spring 3.0和jUnit 4.8,我正在尝试开发一些单元测试。

实际上,我只是尝试在jUnit使用的应用程序上下文中加载的XML中定义的测试用例中使用依赖注入设置bean的属性(文件)。

我正在使用使用jUnit 4 aproach的注释加载的XML文件配置。这是所有测试类使用的主要BaseTest:

@ContextConfiguration("/test-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
@Ignore
public class BaseTest { ... }

这是test-context.xml

的一部分
<context:component-scan base-package="com.test" />  

<bean id="ExtractorTest" class="com.test.service.ExtractorTest">
    <property name="file" value="classpath:xls/SimpleFile.xls"></property>
</bean>

所以我在我的课程中尝试使用测试(ExtractorTest)只是设置了'file'属性,并在类路径中加载了一个文件,没有别的。

以下是带测试的类的一部分:

public class ExtractorTest extends BaseTest {

    private Resource file;
    private InputStream is;

    public void setFile(Resource file) {
        this.file = file;
    }

    @Before
    public void init() {
        this.is = this.getClass().getResourceAsStream("/xls/SimpleFile.xls");
        Assert.assertNotNull(is);
    }

    @Test
    public void testLoadExcel() throws IOException {
        // file is always null, but the InputStream (is) isn't!
        Assert.assertNotNull(file.getFile());
        InputStream is = new FileInputStream(file.getFile());
        HSSFWorkbook wb = new HSSFWorkbook(new POIFSFileSystem(is));
        // todo...
    }

}

问题是setter工作,因为我添加了一个断点,Spring正在设置它的属性ok。但是当测试方法启动时它为null,可能是因为它是另一个正在运行的实例,但为什么呢?如何使用应用程序上下文的XML设置要加载的“文件”以进行测试?我无法使用jUnit分配它,我不明白为什么以及如何做到这一点。我试图避免在@Before方法中写作,但我不知道这绝对是一个好方法......

谢谢。

PD:抱歉我的英语; - )

1 个答案:

答案 0 :(得分:3)

您的配置不起作用,因为Spring没有创建JUnit使用的ExtractorTest实例;相反,实例由JUnit创建,然后传递给Spring进行后期处理。

您看到的效果是因为应用程序上下文创建了一个标识为ExtractorTest的bean,但没有人使用它。

伪代码:

ApplicationContect appContext = new ...
appContext.defineBean("ExtractorTest", new ExtractorTest()); // Calls setter

ExtractorTest test = new ExtractorTest(); // Doesn't call setter
test.postProcess(appContext); // inject beans from appContext -> does nothing in your case

所以解决方案是定义一个bean file

<bean id="file" class="..." />

(参见文档如何构建Resource bean),然后让Spring注入:

@Autowired
private Resource file;