粗糙的研究了下Spring test,分享以下blog:
1. http://blog.csdn.net/shan9liang/article/details/40452469
2. http://www.ibm.com/developerworks/cn/java/j-lo-springunitest/
3. http://blog.csdn.net/feihong247/article/details/7828143
其实主要看了第一个blog,然后就下手写test了,推荐着重看看第二个blog,更详细。
之前也尝试过在Spring的项目中直接使用Junit进行单元测试,但如果涉及到配置文件的加载/数据库的操作,会带来很多麻烦。具体问题和原因可参考第一个blog。
自己动手写的TestCase如下: (留个备份,便于查阅)
被测试项目的大致结构如上。 各个类如下:
LogDAO:
public interface LogDAO { public void save(Log log); }
UserDAO:
public interface UserDAO { public void save(User user); public int findAll(); }
LogDAOImpl:
@Component(value = "logDAO") public class LogDAOImpl implements LogDAO { private SessionFactory sessionFactory; @Autowired(required = true) public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override public void save(Log log) { Session session = sessionFactory.getCurrentSession(); session.save(log); } }
UserDAOImpl:
public class UserDAOImpl implements UserDAO { private SessionFactory sessionFactory; @Resource public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override public void save(User user) { /*Connection connection = null; try { connection = dataSource.getConnection(); Statement statement = connection.createStatement(); String insertStr = "insert into user values(null,"hehe")"; statement.executeUpdate(insertStr); } catch (SQLException e) { e.printStackTrace(); } finally { try { if (connection != null){ connection.close(); } } catch (SQLException e) { e.printStackTrace(); } }*/ /*Session session = sessionFactory.openSession(); session.beginTransaction(); session.save(user); session.getTransaction().commit();*/ Session session = sessionFactory.getCurrentSession(); session.save(user); } @Override public int findAll() { Session session = sessionFactory.getCurrentSession(); String query_sql = "select id,name from user"; Query query = session.createSQLQuery(query_sql).addEntity(User.class); return query.list().size(); } }
Log:
@Entity @Table(name = "t_log") public class Log { private int id; private String msg; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
User:
@Entity public class User { private String name; private int id; public String getName() { return name; } public void setName(String name) { this.name = name; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } }
UserService:
public class UserService { private UserDAO userDAO; private LogDAO logDAO; @Resource public void setLogDAO(LogDAO logDAO) { this.logDAO = logDAO; } @Autowired public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } @Transactional public void add(User user){ userDAO.save(user); Log log = new Log(); log.setMsg("a user has been added!"); logDAO.save(log); } public int findAllUsers(){ return userDAO.findAll(); } }
jdbc.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/spring jdbc.username=root jdbc.password= ####################### hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring-config.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <context:annotation-config /> <context:component-scan base-package="foo.bar"/> <bean id="userDAO" class="foo.bar.dao.Impl.UserDAOImpl"/> <bean id="userService" class="foo.bar.service.UserService"> <property name="userDAO" ref="userDAO"/> <property name="logDAO" ref="logDAO"/> </bean> <bean id="logIntercept" class="foo.bar.proxy.LogInterceptor"/> <aop:config> <aop:pointcut id="log" expression="execution(public void foo.bar.dao.Impl.UserDAOImpl.save(foo.bar.entity.User))"/> <aop:aspect id="logAspect" ref="logIntercept"> <aop:before method="before" pointcut-ref="log"/> </aop:aspect> </aop:config> <context:property-placeholder location="jdbc.properties"/> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="annotatedClasses"> <list> <value>foo.bar.entity.User</value> <value>foo.bar.entity.Log</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.format_sql">true</prop> </props> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
Main:
public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); UserService service = context.getBean(UserService.class); User user = new User(); user.setId(10); user.setName("Chris"); service.add(user); } }
其实说白了,就是将Main转换成测试类。
BaseClass:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:spring-config.xml") @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) public class BaseClass { }
如果测试类继承BaseClass,则测试类无需再配置@RunWith,@ContextConfiguration以及@TransactionConfiguration。
其中的@TransactionConfiguration很重要,它控制测试过程中产生的事务是否回滚。
UserServiceTest:
public class UserServiceTest extends BaseClass{ @Resource private UserService userService; @Test @Transactional //若使用事务,则使用该注解 //@Rollback(false) //可用来覆盖全局的TransactionConfiguration public void testAdd() throws Exception { User user = new User(); user.setName("hehe"); user.setId(100); userService.add(user); Assert.assertEquals(8, userService.findAllUsers()); } }