Java @Test后回滚事务
首先,我在StackOverflow上找到了很多关于这个的帖子,但是没有一个对我有帮助,所以很抱歉问了可能重复的问题 我正在使用SpringTest运行JUnit测试,我的代码如下所示Java @Test后回滚事务,java,spring,hibernate,junit,spring-test,Java,Spring,Hibernate,Junit,Spring Test,首先,我在StackOverflow上找到了很多关于这个的帖子,但是没有一个对我有帮助,所以很抱歉问了可能重复的问题 我正在使用SpringTest运行JUnit测试,我的代码如下所示 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {}) public class StudentSystemTest { @Autowired private StudentSystem st
@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,您需要使用Spring上下文和事务管理器运行测试,例如
@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参考的章节 只需在测试顶部添加
@Transactional
注释:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"testContext.xml"})
@Transactional
public class StudentSystemTest {
默认情况下,Spring将围绕您的测试方法启动一个新的事务,并在回调之前/@之后
启动一个新事务,在回调结束时回滚。它在默认情况下工作,在上下文中有一些事务管理器就足够了
发件人:(粗体):
在TestContext框架中,事务由TransactionalTestExecutionListener管理。请注意,TransactionalTestExecutionListener
默认配置为,即使您没有在测试类上明确声明@TestExecutionListeners
。但是,要启用对事务的支持,必须在@ContextConfiguration
语义加载的应用程序上下文中提供PlatformTransactionManager
bean。此外,您必须为测试在类或方法级别声明@Transactional
提到添加
@Transactional
的答案是正确的,但是为了简单起见,您可以让您的测试类扩展AbstractTransactionalJUnit4SpringContextTests
您可以禁用回滚:
@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();
}
}
我知道,我发布答案已经太晚了,但希望它能帮助别人。另外,我刚刚解决了我在测试中遇到的这个问题。这是我在测试中得到的: 我的测试班
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "path-to-context" })
@Transactional
public class MyIntegrationTest
上下文xml
<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>
我仍然有一个问题,数据库没有被自动清理
当我将以下属性添加到BasicDataSource时,问题已得到解决
<property name="defaultAutoCommit" value="false" />
希望能有所帮助。旁白:修改托马斯努尔基维茨答案的尝试被拒绝:
这种编辑并没有使文章更容易阅读、更容易查找、更准确或更容易访问。更改要么完全多余,要么严重损害可读性
有关集成测试的文档的相关部分正确且永久 要启用对事务的支持,必须在通过
@ContextConfiguration
语义加载的ApplicationContext
中配置PlatformTransactionManager
bean
@配置
@PropertySource(“application.properties”)
公共类持久性{
@自动连线
环境环境;
@豆子
数据源数据源(){
返回新的DriverManager数据源(
env.getProperty(“datasource.url”),
env.getProperty(“datasource.user”),
env.getProperty(“datasource.password”)
);
}
@豆子
平台transactionManager transactionManager(){
返回新的DataSourceTransactionManager(dataSource());
}
}
此外,您必须在测试的类或方法级别声明Spring的@Transactional
注释
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(类={Persistence.class,SomeRepository.class})
@交易的
公共类SomeRepositoryTest{…}
使用@Transactional
注释测试方法会导致测试在事务中运行,默认情况下,该事务将在测试完成后自动回滚。如果用@Transactional
注释测试类,则该类层次结构中的每个测试方法都将在事务中运行
除了在
@Test
方法上添加@Transactional
,您还需要添加@Rollback(false)
回滚是什么意思?。清理数据库?将其设置为与执行initTest
后完全相同的状态好吧,我以前尝试过这个,但仍然不起作用,可能。。。问题是我没有定义PlatformTransactionManager,我该怎么做?@javo:你是如何修改数据库的?如果您使用的是Jpa/Hibernate/JdbcTemplate/。。。必须有一些平台TransactionManager
。否则Spring将如何知道您的事务和数据库?此答案中的链接不再正确;请参阅,以获取Spring文档中的正确链接和更多上下文。我不工作,每个方法都需要单独的事务,不能为整个类执行。我正在测试表中的插入。对于@Transactional,甚至不会对数据库发出insert命令(我可以看到这一点,因为控制台有hibernate show sql true)。在很多情况下都很好。但是我的一个测试检查数据库是否因为数据库约束而发出DataAccessException。在这种情况下,测试失败,因为回滚发生在“内存”中,并且从未调用数据库。解决方案:在@Test
方法级别使用@Transactional
,而不是在类级别。这与OP要求的正好相反。这应该是对已接受答案的注释。那么,您手动提交您的语句了吗?你确定你的数据已经写入了你的数据库吗?对于那些努力理解Spring事务的人来说,请确保你的数据源没有设置为自动提交,否则你会发疯,试图弄明白为什么@Transactional似乎什么都不做。在类级别添加注释“@Transactional”是行不通的,正在添加批注“@Transactional”separa