Java 如何在Junit测试中自动连线(一般新手查询)

Java 如何在Junit测试中自动连线(一般新手查询),java,spring,hibernate,unit-testing,junit,Java,Spring,Hibernate,Unit Testing,Junit,这是关于Spring和创建应用程序上下文的一般问题 我正在为一个网站应用程序进行单元测试。该网站使用Spring和Hibernate,我想用数据库中的一些数据进行测试。我不知道如何将SpringIoC容器连接到我的单元测试。我知道applicationContext.xml的位置,但是如何在单元测试中访问它的bean呢 这是我的密码: package com.example.test; import junit.framework.Assert; import org.hibernate.Se

这是关于Spring和创建应用程序上下文的一般问题

我正在为一个网站应用程序进行单元测试。该网站使用Spring和Hibernate,我想用数据库中的一些数据进行测试。我不知道如何将SpringIoC容器连接到我的单元测试。我知道applicationContext.xml的位置,但是如何在单元测试中访问它的bean呢

这是我的密码:

package com.example.test;

import junit.framework.Assert;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

public class SessionFactoryTest {

    @Autowired
    SessionFactory sessionFactory;

    @Test
    public void testSessionFactoryAutowiring() {
         Session session = sessionFactory.getCurrentSession();
         Assert.assertEquals(session.getClass(),Session.class);
    }
}
这就产生了错误

Testsuite: com.example.test.SessionFactoryTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0.011 sec

Testcase: testSessionFactoryAutowiring took 0.002 sec
Caused an ERROR
null
java.lang.NullPointerException
at com.example.test.SessionFactoryTest.testSessionFactoryAutowiring(SessionFactoryTest.java:19)
现在我的问题是,如何从普通的applicationContex.xml访问sessionFactory?我如何进入集装箱?我不介意创建自己的单元测试,但到今天为止,我真的很想编写单元测试。谁不会呢

更新:我确实根据Spring文档向我的测试类添加了注释

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
但是找不到该文件,我不知道如何指定与测试相关的文件

Testsuite: com.example.test.SessionFactoryTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0.045 sec

Testcase: testSessionFactoryAutowiring took 0.035 sec
Caused an ERROR
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext.xml]; nested exception is java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:81)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
Caused by: java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:158)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:328)
我的项目结构如下所示:

src/
web/WEB-INF/applicationContext.xml
test/java/com/example/SessionFactoryTest.java

并且是用ant构建的。

在位置中使用类路径将不起作用,因为您没有为applicationContext.xml使用默认位置

但这可能会奏效

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "src/stuff web/WEB-INF/applicationContext.xml" })
public class SessionFactoryTest {
我想您的应用程序上下文文件中也有:

<context:component-scan base-package="com.example" />

<bean id="sessionFactory" class="com.example.SessionFactoryImpl" />

您需要声明一个spring测试上下文并用@Runwith注释。xml将进入src/test/resources/my-test-config.xml

@RunWith(SpringJunit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:my-test-config.xml"})
public class myTest { ...

编辑:我不确定,但我想您也需要将hibernate jar添加到测试范围中的类路径中

我将类路径设置为在我的ant build.xml中包含web目录,现在找到了applicationContext.xml。现在我还有其他问题。特别是主applicationContext.xml中的jndi引用。不管怎么说,这就是蚂蚁的任务

<target name="test-platform" depends="compile_tests">
    <mkdir dir="${platform.test.log.dir}"/>
    <junit fork="true" haltonerror="true">
        <classpath refid="test.build.classpath"/>
        <classpath location="test"/>
        <classpath location="${build_testclassdir}"/>
        <batchtest todir="${platform.test.log.dir}">
            <formatter type="plain" usefile="true"/>
            <fileset dir="${javatests}">
                <include name="**/*Test.java"/>
            </fileset>
        </batchtest>
    </junit>
</target>
并将测试上下文放置在test/resources目录中

[david@david web]$ ll test/resources/test-applicationContext.xml 
-rw-rw-r-- 1 david david 4851 Apr  9 16:02 test/resources/test-applicationContext.xml

对于示例代码,您应该在会话工厂单元测试中测试SessionFactory的返回值


如果你想在一个单元测试中注入依赖关系,考虑使用像McKooOnEng注之类的东西来自动将模拟对象注入到被测试类

中,你能重新措辞“XML来”吗?我很难解析它。通常的项目结构看起来像这样。很抱歉,这对我来说仍然没有意义,我正在尝试找出如何在
@ContextConfiguration(locations={})
注释中指定applicationContext.xml的位置。你能解释一下怎么做吗?你的项目中需要一个testresource文件夹。按照惯例,您将单元测试中需要的文件放在src/test/resources中,并将单元测试放在src/test/javamaven中。您是否使用maven构建?我确实以
@ContextConfiguration(locations={“web/web-INF/applicationContext.xml”)的形式尝试过这一点
但这不起作用。我能够在ant中为测试执行的范围设置类路径。但是我仍然无法实例化bean。想法?你能粘贴一下你的应用程序上下文吗?编辑你的帖子,包括问题和应用程序上下文内容。顺便说一下,单元测试不应该有任何依赖项,因此您应该模拟依赖项。你可以使用EasyMock来实现这个目的。你想做集成测试,亨里克,很好。我需要编写的测试是专门针对数据库中某个表中的所有现有的、真实的数据测试某个方法的行为?以及应用程序上下文内容?Henrik,感谢您的回复。现在一切正常(我的首席技术官很高兴,这很酷)。正如我在回答中提到的,这是一个评论,我需要基本上做3件事,1。创建一个ant目标,并将类路径设置为包含测试目录。2.在位置指向test-applicationContext.xml的测试类上添加Transaction、RunWith和ContextConfiguration注释。3.在应用程序上下文中设置org.apache.commons.dbcp.BasicDataSource以不依赖jndi。最后,这允许我在测试类中自动连接sessionFactory,这就是目标。嗯
[david@david web]$ ll test/resources/test-applicationContext.xml 
-rw-rw-r-- 1 david david 4851 Apr  9 16:02 test/resources/test-applicationContext.xml