我在测试我的dao时遇到了很多麻烦。 我将在最后显示代码。
问题是:
当我尝试在dataDao中测试不同的方法时:addData& updateData,我想重新开始一个干净的插槽。 如果我在添加后调用更新,我不希望在addData的测试中添加数据。
我在setUp中打开一个会话,并在tearDown中关闭它,并使用@Before和@After重新注释。 hibernate配置是create-drop,因此每次关闭和重新打开会话时表都是新的。
我对休眠有点新意,但我做了我的研究并在网上查了很长时间/周。
这是我正在测试的两个类:DataDAO和MyDaoManager(因为有多个表而使用了他)
提前感谢您的帮助,
MyDaoManager.java
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public abstract class MyDaoManager<T> {
private SessionFactory sessionFactory = null ;
/**
* <h2>Constructor which will get the sessionFactory from the class HibernateUtil</h2>
*/
public MyDaoManager(){
this.sessionFactory = HibernateUtil.getSessionFactory() ;
}
/**
* <h2>Method which gets the SessionFactory.</h2>
* @return A SessionFactory.
*/
public SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* <h2>Method which sets the SessionFactory at the moment of the construction.</h2>
* @param sessionFactory The SessionFactory to set.
*/
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/**
* <h2>Method which adds a given object from the model in the database.</h2>
* @param object Object to add.
*/
public boolean add(T object){
Session session = getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
try {
session.save(object);
transaction.commit();
}
catch (RuntimeException e){
transaction.rollback();
throw e ;
}
return true;
}
/**
* <h2>Method which updates a given Object from the model in the database.</h2>
* @param object Object to update.
*/
public void update(T object){
Session session = getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
try {
session.merge(object);
transaction.commit();
}
catch (RuntimeException e){
transaction.rollback();
throw e ;
}
}
/**
* <h2>Method which saves or updates a given Object from the model in the database.</h2>
* @param object Object to update.
*/
public void saveOrUpdate(T object){
Session session = getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
try {
session.saveOrUpdate(object);
transaction.commit();
}
catch (RuntimeException e){
transaction.rollback();
throw e ;
}
}
/**
* <h2>Method which gets an object from the model thanks to its id in the database.</h2>
* @param id The object's id to get.
* @return An object.
*/
public abstract T getOne(int id);
/**
* <h2>Method which gets all of an object from the model.</h2>
* @return A list of the object.
*/
public abstract List<T> getAll();
/**
* <h2>Method which deletes a given object thanks to its id.</h2>
* @param id The object's id to delete.
*/
public abstract void delete(int id);
}
这是dataDao.java:
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class DataDao extends MyDaoManager<Data>{
@Override
public Data getOne(int id) {
Session session = getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
Data data = null;
try {
Query query = session.createQuery("from Data d where d.id= :id").setParameter("id", id);
data = (Data)query.uniqueResult();
transaction.commit();
}
catch (RuntimeException e){
transaction.rollback();
throw e ;
}
return data;
}
@SuppressWarnings("unchecked")
@Override
public List<Data> getAll() {
Session session = getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
List<Data> list = null;
try {
list = session.createQuery("from Data d").list();
transaction.commit();
}
catch (RuntimeException e){
transaction.rollback();
throw e ;
}
return list;
}
@Override
public void delete(int id) {
Session session = getSessionFactory().getCurrentSession();
Data data = getOne(id);
Transaction transaction = session.beginTransaction();
try {
session.delete(data);
transaction.commit();
}
catch (RuntimeException e){
transaction.rollback();
throw e ;
}
}
}
这是我的测试,DataDaoTest.java:
import static org.junit.Assert.assertTrue;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.hibernate.Session;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class DataDaoTest{
private Session session;
private DataDao dataDao;
@Before
public void setUp(){
session = HibernateUtil.getSessionFactory().openSession();
dataDao = new DataDao();
dataDao.setSessionFactory(session.getSessionFactory());
}
@After
public void tearDown(){
session.close();
}
@Test
public void addDataTestShouldWork(){
Data dataTest = new Data();
dataTest.setDate(new Date(System.currentTimeMillis()));
dataTest.setSensor(new Sensor());
dataTest.setValue("test");
dataTest.setIsOnPhone(true);
assertTrue("No add",dataDao.add(dataTest));
List<Data> founded = dataDao.getAll();
DataEqualsBuilder dataEqualsBuilder = new DataEqualsBuilder(dataTest);
assertTrue("Not the same object added and founded", dataEqualsBuilder.equals(founded.get(0)));
}
@Test(expected=RuntimeException.class)
public void addDataTestShouldNotWork(){
dataDao.add(null);
}
@Test
public void updateDataTestShouldWork(){
Data dataTest = new Data();
dataDao.add(dataTest);
dataTest.setValue("test1");
dataDao.update(dataTest);
List<Data> founded = dataDao.getAll();
DataEqualsBuilder dataEqualsBuilder = new DataEqualsBuilder(dataTest);
assertTrue("Not the same object added and founded", dataEqualsBuilder.equals(founded.get(0)));
}
public class DataEqualsBuilder extends EqualsBuilder {
private Data data;
public DataEqualsBuilder( Data data){ this.data= data; }
@Override
public boolean equals(Object obj) {
if (obj == null) { return false; }
if (obj == this) { return true; }
if (obj.getClass() != data.getClass()) {
return false;
}
Data rhs = (Data) obj;
return (DataEqualsBuilder.reflectionEquals(data, rhs, "sensor"));
}
}
}
最后我的hibernate配置:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/APISensor</property>
<!-- TODO create specific user -->
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">false</property>
<property name="hbm2ddl.auto">create-drop</property>
</session-factory>
</hibernate-configuration>
答案 0 :(得分:1)
尝试删除此Hibernate属性:
<property name="current_session_context_class">thread</property>
将您的设置/ tearDown更改为:
@Before
public void setUp(){
session = HibernateUtil.getSessionFactory().openSession();
ThreadLocalSessionContext.bind(session);
dataDao = new DataDao();
dataDao.setSessionFactory(session.getSessionFactory());
}
@After
public void tearDown(){
session.close();
ThreadLocalSessionContext.unbind(sessionFactory);
}