【问题标题】:Spring dependency injection null when running a test case运行测试用例时Spring依赖注入null
【发布时间】:2012-07-31 09:18:48
【问题描述】:

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

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

我正在使用使用 jUnit 4 方法的注释加载的 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) 只是在类路径中加载一个文件来设置“文件”属性,仅此而已。

这里是测试类的一部分:

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 正在设置它的属性。但是当测试方法启动时它为空,可能是因为它是另一个正在运行的实例,但为什么呢?如何使用应用程序上下文的 XML 设置要加载的“文件”以进行测试?我无法使用 jUnit 分配它,我不明白为什么以及如何去做。我试图避免在 @Before 方法中写入,但我不知道这绝对是一个好方法......

谢谢。

PD:对不起我的英语;-)

【问题讨论】:

    标签: java spring dependency-injection junit


    【解决方案1】:

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

    您看到的效果是因为应用程序上下文创建了一个 id 为 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
    

    所以解决办法是定义一个beanfile

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

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

    @Autowired
    private Resource file;
    

    【讨论】:

    • 谢谢亚伦!和你说的完全一样。我不知道这是否是在 Spring 和 jUnit 中使用测试文件的最佳方法,因为它代表了许多要定义的新 bean(每个要使用的测试文件 1 个)但它可以工作。在 @Before 方法中分配它可能是更好的主意......无论如何,再次感谢您!
    猜你喜欢
    • 2010-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多