@Test之后的回滚事务

时间:2012-09-27 17:00:24

标签: java spring hibernate junit spring-test

首先,我在StackOverflow上发现了很多关于此的线程,但是没有一个真正帮助过我,所以很抱歉可能会重复提问。

我正在使用spring-test运行JUnit测试,我的代码看起来像这样

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations = {})
public class StudentSystemTest {

    @Autowired
    private StudentSystem studentSystem;

    @Before
    public void initTest() {
    // set up the database, create basic structure for testing
    }

    @Test
    public void test1() {
    }    
    ...  
}

我的问题是我希望我的测试不会影响其他测试。 所以我想为每个测试创建类似回滚的东西。 我为此搜索了很多,但到目前为止我一无所获。 我正在使用Hibernate和MySql

7 个答案:

答案 0 :(得分:109)

只需在测试之上添加@Transactional注释:

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations = {"testContext.xml"})
@Transactional
public class StudentSystemTest {

默认情况下,Spring会围绕您的测试方法和@Before / @After回调启动一个新事务,最后回滚。它默认工作,它足以在上下文中有一些事务管理器。

来自:10.3.5.4 Transaction management(我的大胆):

  

在TestContext框架中,事务由TransactionalTestExecutionListener管理。请注意,TransactionalTestExecutionListener默认配置为 ,即使您未在测试类中明确声明@TestExecutionListeners也是如此。但是,要启用对事务的支持,必须在PlatformTransactionManager语义加载的应用程序上下文中提供@ContextConfiguration bean。此外,您必须在测试的类或方法级别声明@Transactional

答案 1 :(得分:14)

旁白:试图修改Tomasz Nurkiewicz的答案被拒绝了:

  

此修改不会使帖子更容易阅读,更容易找到,更准确或更易于访问。变化要么完全是多余的,要么是主动损害可读性。         

正确且永久link到有关集成测试的相关文档部分。

  

要启用对事务的支持,您必须在通过PlatformTransactionManager语义加载的ApplicationContext中配置@ContextConfiguration bean。

@Configuration
@PropertySource("application.properties")
public class Persistence {
    @Autowired
    Environment env;

    @Bean
    DataSource dataSource() {
        return new DriverManagerDataSource(
                env.getProperty("datasource.url"),
                env.getProperty("datasource.user"),
                env.getProperty("datasource.password")
        );
    }

    @Bean
    PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}
  

此外,您必须在测试的类或方法级别声明Spring的@Transactional注释。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Persistence.class, SomeRepository.class})
@Transactional
public class SomeRepositoryTest { ... }
  

使用@Transactional注释测试方法会导致测试在一个事务中运行,默认情况下,该事务将在测试完成后自动回滚。如果测试类使用@Transactional注释,则该类层次结构中的每个测试方法都将在事务中运行。

答案 2 :(得分:10)

提及添加@Transactional的答案是正确的,但为了简单起见,您可以使用测试类extends AbstractTransactionalJUnit4SpringContextTests

答案 3 :(得分:4)

我知道,我发布答案太迟了,但希望这对某人有帮助。另外,我刚刚解决了我的测试问题。这就是我在测试中所拥有的:

我的考试班

groupName = (EditText) findViewById(R.id.groupName);
groupName.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        Log.d("TEXTHellow",start+" "+before+" "+count);
        if (groupName.length() > 24) {
            groupName.setFocusable(false);
            groupName.setClickable(false);
            groupName.setFocusableInTouchMode(false);
            groupName.setLongClickable(false);
            groupName.setInputType(InputType.TYPE_NULL);
        }
        int remChar=25-count;
        numChar.setText(remChar+"");
    }
    @Override
    public void afterTextChanged(Editable s) {

    }
});

Context xml

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "path-to-context" })
@Transactional
public class MyIntegrationTest 

我仍然遇到问题,数据库没有自动清理。

当我将以下属性添加到BasicDataSource

时,问题已得到解决
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
   <property name="driverClassName" value="${jdbc.driverClassName}" />
   <property name="url" value="${jdbc.url}" />
   <property name="username" value="${jdbc.username}" />
   <property name="password" value="${jdbc.password}" />
</bean>

希望它有所帮助。

答案 4 :(得分:0)

您需要使用sprint上下文和事务管理器运行测试,例如

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations = {"/your-applicationContext.xml"})
@TransactionConfiguration(transactionManager="txMgr")
public class StudentSystemTest {

     @Test
     public void testTransactionalService() {
         // test transactional service
     }

     @Test
     @Transactional
     public void testNonTransactionalService() {
         // test non-transactional service
     }
}

有关更多详细信息,请参阅Spring参考的10. Testing一章。

答案 5 :(得分:0)

除了在/getData/id方法上添加@Transactional,还需要添加@Test

答案 6 :(得分:-5)

您可以停用回滚:

@TransactionConfiguration(defaultRollback = false)

示例:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@Transactional
@TransactionConfiguration(defaultRollback = false)
public class Test {
    @PersistenceContext
    private EntityManager em;

    @org.junit.Test
    public void menge() {
        PersistentObject object = new PersistentObject();
        em.persist(object);
        em.flush();
    }
}