该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-03-25
首先是po, hbm.xml, dao, daoimpl没什么好说的: Customer.java : package rst.spring.mock; import java.io.Serializable; /** @author Hibernate CodeGenerator */ public class Customer implements Serializable { /** identifier field */ private Long id; /** nullable persistent field */ private String name; /** full constructor */ public Customer(String name); { this.name = name; } /** default constructor */ public Customer(); { } public Long getId(); { return this.id; } public void setId(Long id); { this.id = id; } public String getName(); { return this.name; } public void setName(String name); { this.name = name; } } Customer.hbm.xml : <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping package="rst.spring.mock"> <class name="Customer" table="customer"> <id name="id" column="id" type="long" unsaved-value="null"> <generator class="identity"/> </id> <property name="name" column="name" type="string"/> </class> </hibernate-mapping> CustomerDAO : /* * Created on 2005-3-25 */ package rst.spring.mock; import org.springframework.dao.DataAccessException; /** * @author rst * */ public interface CustomerDAO { public void add(Customer customer); throws DataAccessException; } CustomerDAOImpl : package rst.spring.mock; import org.springframework.dao.DataAccessException; import org.springframework.orm.hibernate.support.HibernateDaoSupport; /** * Class description. * * @author rst */ public class CustomerDAOHibernateImpl extends HibernateDaoSupport implements CustomerDAO{ public void add(Customer customer); throws DataAccessException{ this.getHibernateTemplate();.save(customer);; } } 然后测试的基类SpringDAOTestCase继承自AbstractTransactionalDataSourceSpringContextTests,目前只有一个指定测试用xml文件位置的逻辑。 package rst.spring.mock; import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests; /** * Class description. * * @author rst */ public abstract class SpringDAOTestCase extends AbstractTransactionalDataSourceSpringContextTests { protected String[] getConfigLocations(); { return new String[] { "test.xml" }; } } 接着是我们真正测试的类CustomerDAOTest.java: package rst.spring.mock; /** * Class description. * * @author rst */ public class CustomerDaoTest extends SpringDAOTestCase { private CustomerDAOHibernateImpl customerDAO; protected void onSetUpInTransaction(); throws Exception { super.onSetUpInTransaction();; //this.setPopulateProtectedVariables(true);; customerDAO = (CustomerDAOHibernateImpl); this.applicationContext.getBean("customerDAO");; } protected void onTearDownInTransaction(); { customerDAO = null; } public void testInsert(); { Customer customer = new Customer();; customer.setName("javaeye");; customerDAO.add(customer);; String name = (String); jdbcTemplate.queryForObject("select name from customer where id=?", new Object[]{customer.getId();}, String.class);; assertEquals(customer.getName();, name);; } } 最后看看配置文件test.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <!-- - Application context definition for Petclinic on Hibernate. --> <beans> <!-- ========================= RESOURCE DEFINITIONS ========================= --> <!-- Configurer that replaces ${...} placeholders with values from a properties file --> <!-- (in this case, JDBC-related settings for the dataSource definition below); --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"><value>classpath:jdbc.properties</value></property> </bean> <!-- Local DataSource that works in any environment --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"><value>${jdbc.driverClassName}</value></property> <property name="url"><value>${jdbc.url}</value></property> <property name="username"><value>${jdbc.username}</value></property> <property name="password"><value>${jdbc.password}</value></property> </bean> <!-- Hibernate SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"> <property name="dataSource"><ref local="dataSource"/></property> <property name="mappingResources"> <value>rst/spring/mock/Customer.hbm.xml</value> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA); --> <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate.HibernateTemplate"> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> <bean id="customerDAO" class="rst.spring.mock.CustomerDAOHibernateImpl"> <property name="hibernateTemplate"><ref local="hibernateTemplate"/></property> </bean> </beans> 这个文件很简单,不要忘记transactionManager的配置,Test类会自动装配的。 运行之后,就可以看到应有的结果,并且数据库中不会有数据污染。这个过程主要是开始一个transaction,然后开始你的test方法,执行dao操作,执行sql查询验证结果,最后无论成功失败rollback transaction。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2005-03-28
怎么看不懂你的 事务阿 ?
我都是这么写的 。 引用 <bean id="employeeManager" parent="txProxyTemplate">
你那个 事务 声明了 也没用上阿 . |
|
返回顶楼 | |
发表时间:2005-03-29
事务声明仅仅是给AbstractTransactionalDataSourceSpringContextTests使用的,它会根据类型自动装配,然后根据这个事务配置进行事务的启动, 回滚操作。
|
|
返回顶楼 | |
发表时间:2005-03-29
谢谢。我按照你 这个 做成功了。 但是我还想请教你几个问题:
我现在控制台 提示几个警告和error 引用 ERROR [main] (CommonsLoggingLogSystem.java:42) - ResourceManager : unable to find resource 'VM_global_library.vm' in any resource loader.
WARN [main] (AbstractDependencyInjectionSpringContextTests.java:194) - No bean with name 'jdbcTemplate' WARN [main] (AbstractDependencyInjectionSpringContextTests.java:194) - No bean with name 'transactionStatus' WARN [main] (AbstractDependencyInjectionSpringContextTests.java:194) - No bean with name 'managedVariableNames' 不知道为什么会出现这几个警告。 另外一个问题。我看到一些教程 对于这个测试SPRING 下DAO 的数据 保持。问题是 通过DBUTIL 。把数据保存到xml中,然后,测试结束后再 删除 和xml中相同的数据, 而你这里用的是事物回滚 。 我不知道这2种方法 相比较 , 孰优孰劣? |
|
返回顶楼 | |
发表时间:2005-03-29
另外一个问题:关于测试的。
引用 public void testInsert() {
Customer customer = new Customer(); customer.setName("javaeye"); customerDAO.add(customer); String name = (String) jdbcTemplate.queryForObject("select name from customer where id=?", new Object[]{customer.getId()}, String.class); assertEquals(customer.getName(), name); } 比如 我 现在 的论坛, 里面 有[ 栏目]下面有[分论坛]下面有[主题] 而主题这个表 里面还有回复,就是说主题和回复放在一个表里面。 那我现在想测试一下。增加回复功能, 当然 如果测试DAO 还简单些,如果测试的是 Service层, 当我测试 增加回复功能 的时候, public void testInsert(); { BbsMain bbsBack = new BbsMain();; bbsBack.setTitle("回复标题");; bbsBack.setMessage("回复内容");; bbsBack.setBbsFen(bbsFen);; //设置回复所在分论坛 bbsBack.setBbsMain(bbsMain);; //设置回复所属主题 bbsBack.setEmployeeInf(employeeInf);; //设置发帖人 bbsBack.setSendTime(new Date(););; //设置回复时间 bbsBack.setIsTopic("回复");; //设置是回复,而非主题 dao.saveObject(bbsBack);; assertNotNull(bbsBack.getBbsId(););; bbsBack =(BbsMain);dao.getObject(BbsMain.class,bbsBack.getBbsId(););; assertEquals(bbsBackgetTitle();, "555张三");; } 我想请问,这时候 ,那些 栏目,分论坛,主题,发帖人这些 PO 怎么 设定呢? 难道 我们要先 save进 这些.然后再用? 就是 这样 引用 public void testInsert() { BbsSubject bbsSubject = new BbsSubject (); //栏目 bbsSubject.setTitle("栏目名称"); //栏目名称 dao.saveObject(bbsSubject); //增加栏目 BbsFen bbsFen = new BbsFen(); bbsFen.setTitle("分论坛名称"); //分论坛名称 bbsFen.setBbsSubject(bbsSubject); //设置分论坛所属栏目 dao.saveObject(bbsFen); //增加分论坛 EmployeeInf employeeInf = new EmployeeInf(); //发帖人 ............... BbsMain bbsBack = new BbsMain(); bbsBack.setTitle("回复标题"); bbsBack.setMessage("回复内容"); bbsBack.setBbsFen(bbsFen); //设置回复所在分论坛 bbsBack.setBbsMain(bbsMain); //设置回复所属主题 bbsBack.setEmployeeInf(employeeInf); //设置发帖人 bbsBack.setSendTime(new Date()); //设置回复时间 bbsBack.setIsTopic("回复"); //设置是回复,而非主题 dao.saveObject(bbsBack); assertNotNull(bbsBack.getBbsId()); bbsBack =(BbsMain)dao.getObject(BbsMain.class,bbsBack.getBbsId()); assertEquals(bbsBackgetTitle(), "555张三"); } 就是说当测试需要的属性 不在是简单的字符串了.而是一些其他的PO .那这些PO .我们要在这里 都建立一遍么? |
|
返回顶楼 | |
发表时间:2005-03-29
这个只是一个简单的例子,完全可以把dbunit再加进来,dbunit好处就是数据可以分离出来,修改管理都方便。这个时候可以不用dbunit去清理数据,而由spring回滚事务,那样就可以利用到dbunit的好处了。
至于你的service的测试,应该脱离dao进行unit测试,基于接口编程的好处也应该好好用用。 |
|
返回顶楼 | |
发表时间:2005-03-29
rongsantang 写道 这个只是一个简单的例子,完全可以把dbunit再加进来,dbunit好处就是数据可以分离出来,修改管理都方便。这个时候可以不用dbunit去清理数据,而由spring回滚事务,那样就可以利用到dbunit的好处了。
至于你的service的测试,应该脱离dao进行unit测试,基于接口编程的好处也应该好好用用。 不太明白你的意思 ? dbunit好处就是数据可以分离出来 是什么意思 ? 你为什么 说 这个阿 简单 的例子 。。。。简单不简单 和 用不用 dbunit有关系么 ? 引用 至于你的service的测试,应该脱离dao进行unit测试
是什么意思 ? 我主要想 请教 你 ,那 里面的 PO 是不是都需要手工的去构造出来 ? |
|
返回顶楼 | |
发表时间:2005-03-29
dbunit可以避免测试对数据造成污染,利用回滚事务可以实现相同目的。
|
|
返回顶楼 | |
发表时间:2005-03-30
zzeric 写道 dbunit可以避免测试对数据造成污染,利用回滚事务可以实现相同目的。
那请问一下。我测试 Service 的时候, 添加回复的时候,需要的 栏目,分论坛,主题等PO 。是不是需要 手工构造出来。就像我写的那样 ? 如果这样,好像比较麻烦阿? |
|
返回顶楼 | |
发表时间:2005-03-30
我有个问题:模仿上面的例子,我做了个测试类,里面使用了getUsers()方法不能回滚.
我的测试方法: public void testGetUsers() { user = new Jiveuser(); user.setName("chen"); dao.saveUser(user); System.out.println("++++++"+dao.getUsers().size()); //assertTrue(dao.getUsers().size() >= 1); } 当不调用dao.getUsers().size()时事务能正常回滚,我使用的数据库为mysql 后台打印出的log显示正常,就是不能回滚,去掉dao.getUsers().size()就行了 ----------------------------------- test: [junit] INFO - AbstractSpringContextTests.loadContextLocations(95) | Loading config for /WEB-INF/applicationContext*.xml [junit] INFO - AbstractTransactionalSpringContextTests.onSetUp(90) | Began t ransaction: transaction manager=[org.springframework.orm.hibernate.HibernateTran sactionManager@1efb4be]; defaultCommit=false [junit] DEBUG - UserDAOImpl.saveUser(45) | userId set to: 1 [junit] INFO - AbstractTransactionalSpringContextTests.onTearDown(106) | Rol led back transaction after test execution -------------------------------------- 我的getUsers()方法 public List getUsers() { return getHibernateTemplate().find("from Jiveuser"); } 请指点 |
|
返回顶楼 | |