Spring Test 中重置自增字段
来源:互联网 发布:西安广电网络营业厅 编辑:程序博客网 时间:2024/05/17 21:43
在集成测试中,对于保存数据到数据库的方法,我们需要验证是否数据被正确地保存到数据库中。
对于使用 Spring 的项目,可以使用 Spring Test DbUnit 和 DbUnit 进行测试。
然而,在数据对比的时候,自增的字段就成了一个障碍,因为自增字段是自动生成的,在测试的时候,我们无法确定下一个插入数据的自增字段的值。
尝试忽略自增 id
首先,我们考虑忽略自增 id,在 @ExpectedDatabase
注解中设置 assertionMode = DatabaseAssertionMode.NON_STRICT
,就会忽略数据集中没有显示声明的字段。但是每一行数据都必须拥有一致的字段。比如
<dataset> <clazz name="clazz1"/> <clazz name="clazz2"/></dataset>
这看起来没有什么大问题,id 会在插入数据的时候自动生成。但是,假设我们有一个学生表,每个学生对应一个班级,问题就来了。比如我们有如下数据集:
<dataset> <clazz name="clazz1"/> <clazz name="clazz2"/> <student name="student1"/> <student name="student2"/></dataset>
这个数据集无法完成初始化,因为我们不知道班级的 id,学生数据就无法插入数据库。所以,我们无法在测试中忽略自增 id。
使用 @DirtiesContext
一个很容易的方法就是使用 Spring 的 @DirtiesContext
注解,然后设置 classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD
,这样会在每个测试方法开始前重新载入新的上下文,包括我们的数据库。这种配置看起来如下
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = {PersistenceContext.class})@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class })@DbUnitConfiguration(dataSetLoader = ColumnSensingReplacementDataSetLoader.class)@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)public class ITTodoRepositoryTest {}
即使这种方法很简单,也解决了我们的问题,但显而易见的是这会降低我们测试的效率,因为每一个测试方法都重新载入一个新的上下文,如果对测试效率有要求,这种方法就不是太适用了。
创建一个能重置自增的帮助类
我们可以创建一个帮助类,来重置指定表的自增 id 字段。
- 创建一个 final 类
DbTestUtil
,然后通过一个私有构造器阻止实例化。 - 在
DbTestUtil
中增加一个静态方法resetAutoIncrementColumns()
,这个方法接受需要重置自增的表名,当前上下文,然后进行重置操作。
要实现这个类,我们需要
- 获得
DataSource
的引用。 - 打开数据库连接。
- 执行重置语句。
下面是一个 DbTestUtil
示例
public final class DbTestUtil { private static final String resetSqlTemplate = "ALTER TABLE %s ALTER COLUMN id RESTART WITH 1"; private DbTestUtil() { } public static void resetAutoIncrementColumns(ApplicationContext applicationContext, String... tableNames) throws SQLException { DataSource dataSource = applicationContext.getBean(DataSource.class); try (Connection dbConnection = dataSource.getConnection()) { for (String resetSqlArgument : tableNames) { try (Statement statement = dbConnection.createStatement()) { String resetSql = String.format(resetSqlTemplate, resetSqlArgument); statement.execute(resetSql); } } } }}
这里的重置语句是 H2 数据库的语法。有了这个方法后,我们在测试前就可以进行调用。
@Beforepublic void setUp() throws SQLException { DbTestUtil.resetAutoIncrementColumns(applicationContext, "student", "clazz");}
- Spring Test 中重置自增字段
- 重置自增字段
- postgresql重置自增字段
- SQL Server 自增字段重置
- SQL Server 自增字段重置
- sql 重置数据库自增字段
- 重置数据库自增长字段
- 关于自增字段的序列重置(亲测)
- MYSQL 重置自增
- spring mybates 自增字段返回id
- 如何重置MySQL中表中自增列的初始值
- SQL Server 自增字段重置回0 分保留数据和不保留数据
- [sql server] 重置自增
- sqlserver 重置自增Id
- SqlServer 重置自增主键
- SQL重置自增列
- 重置Mysql中auto_increment字段初始值
- SQL server中设置自增字段
- CCF-训练50题-NO.23-锤子剪刀布
- Javascript知识点总结(六)
- 【BZOJ2049】洞穴勘测(Link-Cut Tree)
- c++实战应用-1
- vim的跨文件复制粘贴
- Spring Test 中重置自增字段
- 图片加载原理
- PHPExcel 读取Excel以xlsx格式的文件
- UVA 12657
- 121. Best Time to Buy and Sell Stock
- 北京师范大学第十四届ACM决赛- B Squared Permutation 三分
- Island Perimeter 经典解法
- BM服务器远程管理模块IMM接口IP设置
- JS中for 循环 与 for in 循环的区别