【问题标题】:Rollback sequence after unit test单元测试后的回滚顺序
【发布时间】:2017-09-15 15:13:03
【问题描述】:

我正在使用 spring-test 运行 JUnit 测试,我的代码如下所示:

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations = {})
@Transactional (propagation = Propagation.REQUIRED)
@Rollback
public class MyTest {

    @Autowired
    private MyRepository repository;

    @Before
    public void before() {
       //clean repository
    }

    @Test
    public void test_1() {
       //add new entity
    }   

    @Test
    public void test_2() {
      //add new entity
    } 
    ...  
}

我想在所有测试之前回滚我的数据库。并且表回滚,但 id 生成的顺序随着每次测试而增加。

请帮助我找到在每次测试前设置起始值序列的方法。

我正在使用 Spring、Hibernate、HsqlDb

【问题讨论】:

  • 您应该使用在每次测试之间创建和删除的嵌入式数据库。或者至少创建一个新架构并将其删除。

标签: java hibernate junit spring-test


【解决方案1】:

如果您使用 @Transactional 调用方法,则无法进行回滚。您可以做的是 @After 以删除所有数据库,并在 @Before 中再次创建它。我认为这不是一个好主意,您应该删除这些值以隔离每个测试。我建议你使用H2数据库,以便能够在内存存储中使用,所以你不必担心id号。

你必须在 pom 中添加这个依赖:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.193</version>
</dependency>

.xml里面的配置应该是这样的:

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>
        <property name="hibernate.connection.url">jdbc:h2:mem:testDB;DATABASE_TO_UPPER=false;DB_CLOSE_DELAY=-1</property>
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="show_sql">false</property>
        <property name="hbm2ddl.auto">create</property>
    </session-factory>
</hibernate-configuration>

当然,您应该调整它以适应您的系统,但您必须保留该用户名和密码才能成功连接。

如果您不想自动创建表格,可以在连接 URL 上添加此参数:

INIT=RUNSCRIPT FROM 'classpath:scripts/create.sql

这将在测试之前运行您的脚本。

然后在你的测试中你可以做一些链接这个:

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations = {})
@Transactional (propagation = Propagation.REQUIRED)
public class MyTest {

    @Autowired
    private MyRepository repository;

    @Test
    public void test_1() {
       //add new entity
    }   

    @Test
    public void test_2() {
      //add new entity
    } 

    @After
    public void tearDown(){
      repository.clean();
    }
}

而干净的方法可能是这样的

public void clean(){
    for (T obj: this.findall()) //replacing T for the type if you don't use generics
        session.delete(obj); //your entity manager or session, depending on how you do the queries
}

【讨论】:

    猜你喜欢
    • 2012-11-26
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多