首页 > 数据库技术 > 详细

Spring DBUnit 插入数据的时候如何处理自增ID

时间:2018-08-20 22:22:55      阅读:519      评论:0      收藏:0      [点我收藏+]

Spring DBUnit 插入数据的时候如何处理自增ID

今天在补单元测试的时候遇到一个问题,在给插入数据的方法写单元测试的时候,第一遍运行的时候是没问题,第二遍运行就报错了,如下:

junit.framework.ComparisonFailure: value (table=FACULTY_ROOM, row=2, col=id) 
Expected :3
Actual   :4
 <Click to see difference>
   at org.dbunit.assertion.JUnitFailureFactory.createFailure(JUnitFailureFactory.java:39)
    at org.dbunit.assertion.DefaultFailureHandler.createFailure(DefaultFailureHandler.java:97)
    at org.dbunit.assertion.DefaultFailureHandler.handle(DefaultFailureHandler.java:223)
    at org.dbunit.assertion.DbUnitAssert.compareData(DbUnitAssert.java:524)
    at org.dbunit.assertion.DbUnitAssert.assertEquals(DbUnitAssert.java:409)
    at org.dbunit.assertion.DbUnitAssert.assertEquals(DbUnitAssert.java:312)
    at org.dbunit.assertion.DbUnitAssert.assertEquals(DbUnitAssert.java:274)
    at org.dbunit.assertion.DbUnitAssert.assertEqualsIgnoreCols(DbUnitAssert.java:122)
    at org.dbunit.Assertion.assertEqualsIgnoreCols(Assertion.java:74)
    at com.github.springtestdbunit.assertion.NonStrictDatabaseAssertion.assertEquals(NonStrictDatabaseAssertion.java:56)
    at com.github.springtestdbunit.assertion.NonStrictDatabaseAssertion.assertEquals(NonStrictDatabaseAssertion.java:48)
    at com.github.springtestdbunit.DbUnitRunner.verifyExpected(DbUnitRunner.java:154)
    at com.github.springtestdbunit.DbUnitRunner.verifyExpected(DbUnitRunner.java:120)
    at com.github.springtestdbunit.DbUnitRunner.afterTestMethod(DbUnitRunner.java:86)
    at com.github.springtestdbunit.DbUnitTestExecutionListener.afterTestMethod(DbUnitTestExecutionListener.java:190)
    at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:319)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:94)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)`

第一遍运行成功是因为第一次插入数据到测试数据库时,从原始数据ID=2增长到ID=3,和预期一致,后面执行完毕,数据虽然回滚删除了,但是自增ID的游标没变,下次插入数据ID就是从4开始的,所以与预期的ID=3不一致,我的代码和数据文件如下:

@Test
@ExpectedDatabase(value = "facultyService.createFaculty.expectedData.xml", assertionMode = DatabaseAssertionMode.NON_STRICT)
public void testCreateFaculty() {
    Faculty faculty = new Faculty();
    faculty.setCode("rjgc");
    faculty.setName("软件工程");
    faculty.setAbbreviation("rjgc");
    facultyService.createFaculty(faculty);
}


<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<FACULTY id="1" code="jsj" name="计算机系" abbreviation="jsj"/>
<FACULTY id="2" code="cstmgc" name="测试更新土木工程系" abbreviation="cstmgc"/>
</dataset>

解决方法:在插入操作之前把ID自增的游标定位到当前初始数据的最大ID处,下一次插入数据的ID就是最大ID+1,代码如下:

package test.edu.util;

import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public final class DbTestUtil {

    private static final String MAX_ID = "test.reset.sql.maxId";

    private static final String RESET = "test.reset.sql.template";

    private DbTestUtil() {
    }

    public static void resetAutoIncrementColumns(ApplicationContext applicationContext,
                                                 String... tableNames) throws SQLException {
        DataSource dataSource = applicationContext.getBean(DataSource.class);
        String resetSqlTemplate = getResetSqlTemplate(applicationContext, RESET);
        String getMaxIdTemplate = getResetSqlTemplate(applicationContext, MAX_ID);
        try (Connection dbConnection = dataSource.getConnection()) {
            //Create SQL statements that reset the auto increment columns and invoke
            //the created SQL statements.
            for (String resetSqlArgument : tableNames) {
                try (Statement statement = dbConnection.createStatement()) {
                    String maxId = String.format(getMaxIdTemplate, resetSqlArgument);
                    ResultSet resultSet = statement.executeQuery(maxId);
                    if (resultSet.next()) {
                        String id = resultSet.getString(1);
                        String resetSql = String.format(resetSqlTemplate, resetSqlArgument);
                        resetSql = resetSql.replace("maxId", id);
                        statement.execute(resetSql);
                    }
                }
            }
        }
    }

    private static String getResetSqlTemplate(ApplicationContext applicationContext, String option) {
        //Read the SQL template from the properties file
        Environment environment = applicationContext.getBean(Environment.class);
        return environment.getRequiredProperty(option);
    }
}


@DatabaseSetup("facultyService.data.xml")
public class FacultyServiceTest extends BaseServiceTest {
    @Autowired
    private FacultyService facultyService;
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @Before
    public void setUp() throws SQLException {
        DbTestUtil.resetAutoIncrementColumns(applicationContext, "faculty", "faculty_room");
    }
    
    @Test
    @ExpectedDatabase(value = "facultyService.createFaculty.expectedData.xml", assertionMode = DatabaseAssertionMode.NON_STRICT)
    public void testCreateFaculty() {
        Faculty faculty = new Faculty();
        faculty.setCode("rjgc");
        faculty.setName("软件工程");
        faculty.setAbbreviation("rjgc");
        facultyService.createFaculty(faculty);
    }
}

如果还有什么问题,可以在下面留言。

Spring DBUnit 插入数据的时候如何处理自增ID

原文:https://www.cnblogs.com/ekoeko/p/9508250.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!