以前只用用junit做过service层的集成测试,获取实例方法如下:
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = ctx.getBean("userService",UserService.class);
这个做集成测试没有问题,但是做dao层的单元测试就不行了,dao测试类似:
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserDao userDao = ctx.getBean("userDao",UserDao.class);
运行测试用例会报错:
org.hibernate.HibernateException: No Session found for current thread
上网搜索得到的解决办法如下:
在spring配置文件中的sessionFactory这个bean下的hibernateProperties项下添加:
<prop key="hibernate.current_session_context_class">thread</prop>(或者是hibernate.current_session_context_class=thread,看你配置文件的写法)
<property name="hibernateProperties">
<props>
<!-- 指定数据库方言 -->
<!-- 是否根据需要每次自动创建数据库 -->
<!-- 显示Hibernate 持久化操作所生成的SQL -->
<!-- 将SQL脚本进行格式化后在输出 -->
<!-- 解决no session found -->
<prop key="hibernate.current_session_context_class">thread</prop>
</props>
</property>
配置好了再运行,No Session found for current thread的错误消失,但是又有新的错误:
createQuery is not valid without active transaction
再上网搜索,得到的解决方法如下:
配置事务的时候需配置传播特性:propagation="REQUIRED",但是我原本的配置就是这样的啊:
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
最后解决办法是:
引入架包spring-test-3.2.0.RELEASE.jar,修改测试用例的写法,测试通过:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
import com.ycm.model.User;
@RunWith(SpringJUnit4ClassRunner. class)
@ContextConfiguration(locations = { "classpath:beans.xml" })
@TransactionConfiguration(transactionManager="txManager" , defaultRollback=true)
@Transactional
public class UserDaoTest {
@Autowired
private UserDao userDao;
@Test
public void testXxx() {
....//测试用例
}
}
总结:
结合spring-test架包进行junit单元测试,通过注解配置context,@Autowired自动装载注入要测试的类实例,还可可以配置事务,设置自动回滚,测试的时候只需要在数据库中插入几条测试数据就可以放心的测试了,不用担心因为测试而改变了数据库中的数据。设置defaultRollback=true后,测试用例可以多次运行而运行结果不回变,因为数据库中的数据没变,非常好用。当然这也可以根据实际需要设置为true或者false。
2013年3月27日