Java SessionFactory在尝试对DAO类进行单元测试时未自动连接
我遇到了一个奇怪的情况,我定义的sessionFactory在作为web应用程序运行时自动连接到DAO类 然而,当我尝试对这个DAO类进行单元测试时,spring并没有将sessionFactory自动连接到DAO类并抛出下面的异常Java SessionFactory在尝试对DAO类进行单元测试时未自动连接,java,spring,hibernate,unit-testing,sessionfactory,Java,Spring,Hibernate,Unit Testing,Sessionfactory,我遇到了一个奇怪的情况,我定义的sessionFactory在作为web应用程序运行时自动连接到DAO类 然而,当我尝试对这个DAO类进行单元测试时,spring并没有将sessionFactory自动连接到DAO类并抛出下面的异常 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'activityDAO': Injection of autowired dependen
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'activityDAO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory com.adwitiya.vdb.data.activity.ActivityDAO.sessionFactory; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.hibernate.SessionFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:609) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:469) at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84) at com.adwitiya.vdb.data.activity.ActivityDAOTest.testConstructor(ActivityDAOTest.java:31) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at org.junit.runners.ParentRunner.run(ParentRunner.java:300) at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164) at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110) at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175) at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68) Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory com.adwitiya.vdb.data.activity.ActivityDAO.sessionFactory; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.hibernate.SessionFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:506) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284) ... 41 more Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.hibernate.SessionFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:952) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:821) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478) ... 43 more
最后是ActivityDAOTest类
ActivityDAO
-----------
package com.adwitiya.vdb.data.activity;
import com.adwitiya.vdb.domain.Activity;
import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository("activityDAO")
public class ActivityDAO
{
@Autowired
private SessionFactory sessionFactory;
private Session session;
private boolean status;
private static Logger logger = Logger.getLogger(ActivityDAO.class);
public ActivityDAO()
{
try
{
session = sessionFactory.getCurrentSession();
}catch(Exception exception)
{
logger.error(("Unable to initiate session because of the problem " + exception.getMessage()));
}
}
public boolean add(Activity activity)
{
try
{
logger.info("Trying to add an activity " + activity.toString());
session.save(activity);
status = true;
logger.info("Added the activity " + activity.toString() + " successfully");
}catch(HibernateException exception)
{
logger.error("Couldn't add an activity " + activity.toString() + " because of the problem " + exception.getMessage());
}catch(Exception exception)
{
logger.error("Couldn't add an activity " + activity.toString() + " because of the problem " + exception.getMessage());
}
return status;
}
public boolean modify(Activity activity)
{
try
{
logger.info("Trying to modify the activity " + activity.toString());
session.saveOrUpdate(activity);
status = true;
logger.info("Updated the activity " + activity.toString() + "successfully");
}catch(HibernateException exception)
{
logger.error("Couldn't modify the activity " + activity.toString() + " because of the problem " + exception.getMessage());
}catch(Exception exception)
{
logger.error("Couldn't modify the activity " + activity.toString() + " because of the problem " + exception.getMessage());
}
return status;
}
public boolean delete(Activity activity)
{
try
{
logger.info("Trying to delete the activity " + activity.toString());
session.delete(activity);
status=true;
logger.info("Deleted the activity " + activity.toString() + " successfully");
}catch(HibernateException exception)
{
logger.error("Couldn't delete the activity " + activity.toString() + " because of the problem " + exception.getMessage());
}catch(Exception exception)
{
logger.error("Couldn't delete the activity " + activity.toString() + " because of the problem " + exception.getMessage());
}
return status;
}
public SessionFactory getSessionFactory()
{
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
public Session getSession()
{
return session;
}
public void setSession(Session session)
{
this.session = session;
}
public boolean isStatus()
{
return status;
}
public void setStatus(boolean status)
{
this.status = status;
}
}
ActivityDAOTest
---------------
package com.adwitiya.vdb.data.activity;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration( locations = { "classpath:vdb-servlet.xml", "classpath:vdb-data.xml"})
public class ActivityDAOTest
{
public ActivityDAOTest()
{
}
@Test
public void testConstructor()
{
Session thisSession = new Configuration().configure().buildSessionFactory().openSession();
ApplicationContext appcontext = new AnnotationConfigApplicationContext("com.adwitiya.vdb");
ActivityDAO activityDAO = (ActivityDAO) appcontext.getBean("ActivityDAO");
Session session = activityDAO.getSession();
assertEquals(thisSession,session);
}
}
您需要配置JUnit,以便使用注释支持Spring注入:
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
然后,您可以自动连接DAO以进行以下测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration( locations = { "classpath:vdb-servlet.xml", "classpath:vdb-data.xml"})
public class ActivityDAOTest
{
@Autowired
private ActivityDAO activityDAO;
@Test
public void testConstructor(){
activityDAO.methodTotest();
}
}
我想说的是,您所做的是集成测试,而不是单元测试。当我们对SpringBean进行单元测试时,我们会对它们进行隔离测试,即不使用容器,并手动提供依赖项。好的。那么,你能告诉我应该如何进行吗?与其在集成测试中手动创建AnnotationConfigApplicationContext,不如像Benoit建议的那样使用SpringTestContext框架。另外,我们不知道这个会话应该做什么,但是tbh,这并不重要,因为使用
@RunWith(SpringJUnit4ClassRunner.class)
显然是一种选择。好的,谢谢。我会翻阅一些资料,试着找到一种方法。谢谢你,伙计……这似乎很有帮助……但又会出现一些错误:)会试图一次解决一件事。。
ActivityDAOTest
---------------
package com.adwitiya.vdb.data.activity;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration( locations = { "classpath:vdb-servlet.xml", "classpath:vdb-data.xml"})
public class ActivityDAOTest
{
public ActivityDAOTest()
{
}
@Test
public void testConstructor()
{
Session thisSession = new Configuration().configure().buildSessionFactory().openSession();
ApplicationContext appcontext = new AnnotationConfigApplicationContext("com.adwitiya.vdb");
ActivityDAO activityDAO = (ActivityDAO) appcontext.getBean("ActivityDAO");
Session session = activityDAO.getSession();
assertEquals(thisSession,session);
}
}
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration( locations = { "classpath:vdb-servlet.xml", "classpath:vdb-data.xml"})
public class ActivityDAOTest
{
@Autowired
private ActivityDAO activityDAO;
@Test
public void testConstructor(){
activityDAO.methodTotest();
}
}