Spring 使用Junit 进行单元测试
来源:互联网 发布:金山保险箱数据恢复 编辑:程序博客网 时间:2024/04/29 09:22
1.概述
Spring 提供了单元测试的强大支持,主要特性包括:
- 支持主流的测试框架 Junit 和 TestNG
- 支持在测试类中使用依赖注入 Denpendency Injection
- 支持测试类的自动化事务管理
- 支持使用各种注释标签,提高开发效率和代码简洁性
- Spring 3.1 更是支持在测试类中使用非 XML 配置方法和基于 Profile 的 bean 配置模式
2.具体实现
public interface UserDao extends CrudRepository<User, Long>{Page<User> findAll(Pageable pageable);User findById(long id);User findByName(String name);User findByLoginName(String loginName);}
解释:使用data jpa 提供的借口CrudRepository,此接口提供基本的增删改查操作。
@Servicepublic class AccountService implements IAccoutService{@Autowiredprivate UserDao userDao;@Transactionalpublic void saveUser(User user){userDao.save(user);}public List<User> findUserByPage(int page){Pageable pageable = new PageRequest(page, 10);Page<User> page1 = userDao.findAll(pageable);return page1.getContent() ;}public User findUserById(long id){return userDao.findById(id);}public User findUserByLoginName(String name){return userDao.findByLoginName(name);}Logger logger = LoggerFactory.getLogger(AccountService.class);}
配置文件:
<?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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:jpa="http://www.springframework.org/schema/data/jpa"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsdhttp://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd"default-lazy-init="true"><description>Spring公共配置</description><!-- 读配置数据 --><context:property-placeholderignore-resource-not-found="true" location="classpath*:/application.properties" /><!-- 注解支持 --><context:annotation-config /><!-- 使用annotation 自动注册bean,并检查@Required,@Autowired的属性已被注入 --><context:component-scan base-package="com.blueinfo.jee"><context:exclude-filter type="annotation"expression="org.springframework.stereotype.Controller" /><context:exclude-filter type="annotation"expression="org.springframework.web.bind.annotation.ControllerAdvice" /></context:component-scan><!-- Jpa Entity Manager 配置 --><bean id="entityManagerFactory"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><property name="dataSource" ref="dataSource" /><property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" /><property name="packagesToScan" value="com.blueinfo.jee.entity" /><property name="jpaProperties"><props><prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop><prop key="net.sf.ehcache.configurationResourceName">cache/ehcache-hibernate-local.xml</prop><prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop><prop key="hibernate.hbm2ddl.auto">update</prop></props></property></bean><bean id="hibernateJpaVendorAdapter"class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><property name="database" value="POSTGRESQL" /></bean><!-- 数据源配置,使用应用内的DBCP数据库连接池 --><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><!-- Connection Info --><property name="driverClassName" value="${jdbc.driver}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /><property name="defaultAutoCommit" value="false" /></bean><!-- Spring Data Jpa配置, 扫描base-package下所有继承于Repository<T,ID>的接口 --><jpa:repositories base-package="com.blueinfo.jee.reposity.jpa"transaction-manager-ref="transactionManager"entity-manager-factory-ref="entityManagerFactory" /><!-- 事务管理器配置, Jpa单数据源事务 --><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="entityManagerFactory" /></bean><!-- 使用annotation定义事务 --><tx:annotation-driven transaction-manager="transactionManager"proxy-target-class="true" /></beans>
注释:一些基本配置,主要就是使用data jpa 进行数据库操作,Service使用注解扫描。数据库参数在application.properties中设置
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:/applicationContext.xml"}) @Transactional public class AccountServiceTest {@Autowiredprivate AccountService service;@Testpublic void testSaveUser() {User user = new User();user.setEmail("111@qq.com");user.setName("李坏1232");user.setPassword("123456");service.saveUser(user);}}
注释:
3.更多常用测试标签
1,@Configration
@Configurationpublic class SpringConfig {@Autowiredprivate DriverManagerDataSource datasource;//自动注入datasource@Beanpublic UserDao accountDao() {UserDao DAO = new UserDao();DAO.setDataSource(datasource);return DAO;}@Beanpublic AccountService accountService() {return new AccountService();}}
通过SpringConfig定义了UserDao和AccountService
<bean class="config.SpringConfig"/>就可以了。
2,@DirtiesContext
缺省情况下,Spring 测试框架一旦加载 applicationContext 后,将一直缓存,不会改变,但是,
由于 Spring 允许在运行期修改 applicationContext 的定义,例如在运行期获取 applicationContext,然后调用 registerSingleton 方法来动态的注册新的 bean,这样的情况下,如果我们还使用 Spring 测试框架的被修改过 applicationContext,则会带来测试问题,我们必须能够在运行期重新加载 applicationContext,这个时候,我们可以在测试类或者方法上注释:@DirtiesContext,作用如下:
- 如果定义在类上(缺省),则在此测试类运行完成后,重新加载 applicationContext
- 如果定义在方法上,即表示测试方法运行完成后,重新加载 applicationContext
3,@TransactionConfigration 和 @Rollback
4.对junit4标签的支持
1,Test(Expected=...)
public void insertIfNotExist(Account account) { if(account==null) throw new IllegalArgumentException("account is null"); Account acct = accountDao.getAccountById(account.getId()); if(acct==null) { log.debug("No "+account+" found,would insert it."); accountDao.saveAccount(account); } acct = null; }
然后,在测试类中增加一个测试异常的方法,如下:
@Test(expected=IllegalArgumentException.class) public void testInsertException() { service.insertIfNotExist(null); }
运行结果是 green bar。
2,@Test(timeout=3000)
可以给测试方法指定超时时间(毫秒级别),当测试方法的执行时间超过此值,则失败。
比如在 AccountService 中增加如下方法:
public void doSomeHugeJob() { try { Thread.sleep(2*1000); } catch (InterruptedException e) { } }
上述方法模拟任务执行时间 2 秒,则测试方法如下:
@Test(timeout=3000) public void testHugeJob() { service.doSomeHugeJob(); }
上述测试方法期待 service.doSomeHugeJob 方法能在 3 秒内结束,执行测试结果是 green bar。
3,@Repeat
通过 @Repeat,您可以轻松的多次执行测试用例,而不用自己写 for 循环,使用方法:
@Repeat(3) @Test(expected=IllegalArgumentException.class) public void testInsertException() { service.insertIfNotExist(null); }
这样,testInsertException 就能被执行 3 次。
4,@ActiveProfiles
从 Spring 3.2 以后,Spring 开始支持使用 @ActiveProfiles 来指定测试类加载的配置包,比如您的配置文件只有一个,但是需要兼容生产环境的配置和单元测试的配置,那么您可以使用 profile 的方式来定义 beans,如下:
<beans xmlns="http://www.Springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.Springframework.org/schema/beans http://www.Springframework.org/schema/beans/Spring-beans-3.2.xsd"> <beans profile="test"> <bean id="datasource" class="org.Springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.hsqldb.jdbcDriver" /> <property name="url" value="jdbc:hsqldb:hsql://localhost" /> <property name="username" value="sa"/> <property name="password" value=""/> </bean> </beans> <beans profile="production"> <bean id="datasource" class="org.Springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.hsqldb.jdbcDriver" /> <property name="url" value="jdbc:hsqldb:hsql://localhost/prod" /> <property name="username" value="sa"/> <property name="password" value=""/> </bean> </beans> <beans profile="test,production"> <bean id="transactionManager" class="org.Springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="datasource"></property> </bean> <bean id="initer" init-method="init" class="service.Initializer"> </bean> <bean id="accountDao" depends-on="initer" class="DAO.AccountDao"> <property name="dataSource" ref="datasource"/> </bean> <bean id="accountService" class="service.AccountService"> </bean> </beans> </beans>
上面的定义,我们看到:
- 在 XML 头中我们引用了 Spring 3.2 的 beans 定义,因为只有 Spring 3.2+ 才支持基于 profile 的定义
- 在 <beans> 根节点下可以嵌套 <beans> 定义,要指定 profile 属性,这个配置中,我们定义了两个 datasource,一个属于 test profile,一个输入 production profile,这样,我们就能在测试程序中加载 test profile,不影响 production 数据库了
- 在下面定义了一些属于两个 profile 的 beans,即 <beans profile=”test,production”> 这样方便重用一些 bean 的定义,因为这些 bean 在两个 profile 中都是一样的
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/applicationContent.xml") @Transactional @ActiveProfiles("test") public class AccountServiceTest { ... }
- Spring 使用Junit 进行单元测试
- Spring + JUnit进行单元测试
- spring+junit进行单元测试
- 使用JUnit 进行单元测试
- 使用Junit进行单元测试
- 使用Junit进行单元测试
- Spring配合Junit进行单元测试
- Spring整合JUnit进行单元测试
- Spring结合junit进行单元测试
- junit对spring进行单元测试
- Spring整合JUnit框架进行单元测试代码使用详解
- Spring整合JUnit框架进行单元测试代码使用详解
- Spring整合JUnit框架进行单元测试代码使用详解
- Spring整合JUnit框架进行单元测试代码使用详解
- maven下使用 junit对 spring进行单元测试
- 在Spring应用中使用junit进行单元测试
- 使用spring配合Junit进行单元测试的总结
- 使用spring配合Junit进行单元测试的总结
- Android游戏Graphics绘图之图像像素操作
- linux异步IO编程实例分析
- 网站的三大原因容易导致原创不收录
- 【分享】AspxZip v2.0 在线压缩解压ZIP文档
- HDU1452Happy 2004(高次幂取模+积性函数+逆元)
- Spring 使用Junit 进行单元测试
- JAVA性能优化需要注意的26个地方
- VS2008中MFC“资源被另一个编辑器打开”的问题
- asterisk概述和代码解析
- MySQL增量备份
- .net
- 杂记
- JBPM4.4中嵌入自己的用户体系
- VC++美化界面基础