目录
Spring4.1新特性——页面自动化测试框架Spring MVC Test HtmlUnit简介
在Spring 4.1之前我们在准备测试数据时可能通过继承AbstractTransactionalJUnit4SpringContextTests,然后调用executeSqlScript()进行测试,其中存在一个主要问题:如果要同时执行多个数据源的初始化就靠不住了,而且使用起来也不是特别便利,Spring4.1提供了@Sql注解来完成这个任务。
1、初始化Spring配置:
<jdbc:embedded-database id="dataSource1" type="HSQL"/> <jdbc:embedded-database id="dataSource2" type="HSQL"/> <bean id="txManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource1"/> </bean> <bean id="txManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource2"/> </bean>
此处使用jdbc:embedded嵌入数据库来完成测试,数据库使用HSQL。
2、 方法级别的@Sql
@RunWith(SpringJUnit4ClassRunner.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @ContextConfiguration(value = "classpath:spring-datasource.xml") @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class MethodLevelSqlTest { private JdbcTemplate jdbcTemplate1; private JdbcTemplate jdbcTemplate2; @Autowired @Qualifier("dataSource1") public void setDataSource1(DataSource dataSource1) { this.jdbcTemplate1 = new JdbcTemplate(dataSource1); } @Autowired @Qualifier("dataSource2") public void setDataSource2(DataSource dataSource2) { this.jdbcTemplate2 = new JdbcTemplate(dataSource2); } @Test @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql", "classpath:updated-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource1", transactionManager = "txManager1")) public void test01_simple() { Assert.assertEquals( Integer.valueOf(3), jdbcTemplate1.queryForObject("select count(1) from users", Integer.class)); } @Test @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource2", transactionManager = "txManager2")) public void test02_simple() { Assert.assertEquals( Integer.valueOf(2), jdbcTemplate2.queryForObject("select count(1) from users", Integer.class)); } }
方法级别的@Sql在每个方法上都会执行。其中@Sql可以指定多个sql文件,然后通过@SqlConfig指定其编码、分隔符、注释前缀、使用哪个数据源和事务管理器。
3、类级别的@Sql
@RunWith(SpringJUnit4ClassRunner.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @ContextConfiguration(value = "classpath:spring-datasource.xml") @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql", "classpath:updated-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource1", transactionManager = "txManager1")) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class ClassLevelSqlTest { private JdbcTemplate jdbcTemplate1; @Autowired @Qualifier("dataSource1") public void setDataSource1(DataSource dataSource1) { this.jdbcTemplate1 = new JdbcTemplate(dataSource1); } @Test public void test01_simple() { Assert.assertEquals( Integer.valueOf(3), jdbcTemplate1.queryForObject("select count(1) from users", Integer.class)); } }
类级别的对整个测试用例中的每个方法都起作用。
4、指定多个@Sql
Java8之前需要使用@SqlGroup,而Java8之后直接使用多个@Sql注解即可。
@RunWith(SpringJUnit4ClassRunner.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @ContextConfiguration(value = "classpath:spring-datasource.xml") @Transactional() @SqlGroup( { @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql", "classpath:updated-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource1", transactionManager = "txManager1")), @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource2", transactionManager = "txManager2")) } ) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class ClassLevelSqlGroupTest { private JdbcTemplate jdbcTemplate1; private JdbcTemplate jdbcTemplate2; @Autowired @Qualifier("dataSource1") public void setDataSource1(DataSource dataSource1) { this.jdbcTemplate1 = new JdbcTemplate(dataSource1); } @Autowired @Qualifier("dataSource2") public void setDataSource2(DataSource dataSource2) { this.jdbcTemplate2 = new JdbcTemplate(dataSource2); } @Test @Transactional() @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql", "classpath:updated-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource1", transactionManager = "txManager1")) public void test01_simple() { Assert.assertEquals( Integer.valueOf(3), jdbcTemplate1.queryForObject("select count(1) from users", Integer.class)); } @Test @Transactional() @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource2", transactionManager = "txManager2")) public void test02_simple() { Assert.assertEquals( Integer.valueOf(2), jdbcTemplate2.queryForObject("select count(1) from users", Integer.class)); } }
也可以通过元注解把注解合并:
@SqlGroup( { @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql", "classpath:updated-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource1", transactionManager = "txManager1")), @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource2", transactionManager = "txManager2")) } ) @Retention(RUNTIME) @Target(TYPE) @interface CompositeSqlGroup { }
直接使用@CompositeSqlGroup注解即可。
5、事务
@RunWith(SpringJUnit4ClassRunner.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @ContextConfiguration(value = "classpath:spring-datasource.xml") @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class TransactionalTest { private JdbcTemplate jdbcTemplate1; private JdbcTemplate jdbcTemplate2; @Autowired @Qualifier("dataSource1") public void setDataSource1(DataSource dataSource1) { this.jdbcTemplate1 = new JdbcTemplate(dataSource1); } @Autowired @Qualifier("dataSource2") public void setDataSource2(DataSource dataSource2) { this.jdbcTemplate2 = new JdbcTemplate(dataSource2); } @Test @Transactional("txManager1") @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql", "classpath:updated-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource1", transactionManager = "txManager1")) public void test01_simple() { //判断是在事务中执行 Assert.assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); Assert.assertTrue(TestTransaction.isActive()); Assert.assertEquals( Integer.valueOf(3), jdbcTemplate1.queryForObject("select count(1) from users", Integer.class)); } @Test @Transactional("txManager2") @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource2", transactionManager = "txManager2")) public void test02_simple() { Assert.assertEquals( Integer.valueOf(2), jdbcTemplate2.queryForObject("select count(1) from users", Integer.class)); } @Test @Transactional("txManager2") @Sql(value = {"classpath:schema.sql", "classpath:init-data.sql"}, config = @SqlConfig(encoding = "utf-8", separator = ";", commentPrefix = "--", dataSource = "dataSource2", transactionManager = "txManager2")) public void test03_simple() { Assert.assertEquals( Integer.valueOf(2), jdbcTemplate2.queryForObject("select count(1) from users", Integer.class)); TestTransaction.flagForRollback(); } @Rule public TestName testName = new TestName(); @AfterTransaction public void afterTransaction() { System.out.println(testName.getMethodName()); if("test03_simple".equals(testName.getMethodName())) { Assert.assertEquals( Integer.valueOf(0), jdbcTemplate2.queryForObject("select count(1) from users", Integer.class)); } } }
可以使用//判断是在事务中执行TransactionSynchronizationManager.isActualTransactionActive()或TestTransaction.isActive()来判断是否是在事务中执行;通过TestTransaction.flagForRollback();来回滚事务;在测试用例中@AfterTransaction来断言回滚后数据没有插入。
相关文章
Spring4新特性
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
Spring4新特性——注解、脚本、任务、MVC等其他特性改进
源码下载
https://github.com/zhangkaitao/spring4-1-showcase/tree/master/spring4.1-dbtest
相关推荐
Spring 4.1的新特性和增强功能** - **介绍:** 本章节介绍了Spring 4.1版本中新增或改进的功能。 - **知识点:** - **JMS改进(JMS Improvements):** 增强了JMS支持,例如更灵活的消息发送机制。 - **缓存改进...
替代教程通过一个具体的例子——婚礼RSVP应用——来展示如何使用SpringRoo。这个例子包括: - 应用概述:描述应用的功能需求。 - 步骤详解:逐步指导如何使用SpringRoo完成应用开发的各个阶段。 - 最终成果:展示...
- **测试**:提供了对JUnit和TestNG的支持,方便开发者编写单元测试和集成测试。 #### 2.2 理解控制反转 - **控制反转(Inversion of Control, IoC)**:IoC是一种设计模式,其中对象的创建、组装和管理被委托给一...
Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是JavaWeb应用开发的难度,同时有效提升...
Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是JavaWeb应用开发的难度,同时有效提升...
学员将深入学习Spring的核心概念,如Bean的生命周期、依赖注入、AOP的使用等,同时,通过一个具体的Spring应用案例,掌握如何利用Spring进行模块化、组件化开发,提升代码的可维护性和可测试性。 #### 三、...
1. **Spring 4.1**: Spring 是一个开源的应用框架,它提供了全面的企业级应用开发解决方案,包括依赖注入(DI)、面向切面编程(AOP)、事务管理、数据访问/集成、MVC框架等。Spring 4.1版本引入了对Java 8的支持,...
### Spring 3.x企业应用开发实战之实战案例开发——论坛应用 #### 1. 案例概述 在本章中,《Spring 3.x企业应用开发实战》一书通过一个具体的论坛案例,深入介绍了如何使用Spring+Hibernate集成框架进行开发的过程...
4.2 集成测试:检查系统各模块间的协同工作情况,确保整体流程的顺畅。 4.3 压力测试:模拟大量用户并发访问,评估系统的负载能力和稳定性。 第五章 系统上线与维护 5.1 系统部署:将开发完成的系统部署到服务器...
### SSM框架——详细整合教程(Spring+SpringMVC+MyBatis) #### 1、基本概念 **1.1、Spring** Spring 是一个开源框架,最初由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的...
- **集成测试**:验证各模块间的协同工作情况。 - **性能测试**:评估系统的响应速度、负载能力等性能指标。 - **安全测试**:确保系统的安全性,防止恶意攻击。 #### 六、总结与展望 通过《星之语》明星周边产品...
SSM是Java Web开发中常用的三大框架——Spring、Spring MVC和MyBatis的简称。Spring作为核心框架,负责依赖注入和事务管理,提高了代码的可测试性和解耦性;Spring MVC则用于处理HTTP请求和响应,实现业务逻辑与视图...
6.2 测试框架:JUnit和Mockito用于单元测试,Spring Boot Test支持集成测试。 总结,基于SpringBoot的宠物健康顾问系统"pf"充分利用了Spring生态的优势,构建了一个高效、易维护的系统。通过理解其架构、技术选型及...
测试主要包括单元测试、集成测试和性能测试等阶段。最后,将系统部署到服务器上,使其能够在真实的环境中运行。 综上所述,基于SpringBoot+Vue的B2C模式的电子商务平台是一个综合性的项目,涉及到前端、后端以及...
进行单元测试、集成测试和系统测试,确保功能的正确性和性能的稳定性。 第 7 章 结论 乐享田园系统的成功开发,不仅解决了传统土地租赁管理的痛点,还提升了用户体验,为农业领域的信息化管理提供了有效解决方案。...
通过单元测试、集成测试和系统测试,确保系统功能的正确性和性能的稳定性。 第 7 章 结果与总结 7.1 系统成果展示 通过系统截图展示实际运行效果,证明系统设计目标的达成。 7.2 项目总结 回顾开发过程,总结经验...
### 微信小程序大学校园二手教材与书籍拍卖系统源码数据库 #### 一、项目背景与意义 在当今数字化时代,随着应用技术和电子商务平台的快速发展,线上二手交易平台为传统二手交易市场带来了全新的生命力。特别是在...
系统截图展示了界面布局和功能模块,测试环节确保了系统的正确性和性能,包括单元测试、集成测试和系统测试。 7. 总结 本论文详细介绍了基于SSH框架的校园图书网购平台的开发过程,从需求分析到系统实现,再到后期...
#### 四、Spring Data Redis 与 Jedis 的集成使用 ##### 4.1 Spring Data Redis Spring Data Redis 是一个简化 Redis 数据访问的框架,提供了丰富的抽象层和工具类,使得开发者可以更加高效地使用 Redis。 - **配置...
6. **测试**:编写单元测试和集成测试,确保功能正常。 7. **部署**:将项目打包为jar,部署到服务器,配置反向代理如Nginx。 ### 6. 文件结构解析 在"Personal-Blog-Website-main"目录中,你可能会看到以下结构:...