我有
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(defaultRollback = true, transactionManager = "transactionManager")
@Before
@Transactional
public void mySetup() {
// insert some records in db
}
@After
@Transactional
public void myTeardown() {
// delete some records
}
@Test
@Transactional
public void testMy() {
// do stuff
}
我的问题是:mySetup,testMy和myTeardown都会在同一个事务中运行吗?看起来他们应该这样,但我得到一些奇怪的错误,这可能表明他们互相踩着。
答案 0 :(得分:19)
是的,这三种方法都将在同一个交易中运行。请参阅参考文档中的TestContext Framework/Transaction management部分:
任何之前的方法(例如使用JUnit的@Before注释的方法)和任何后续方法(例如使用JUnit的@After注释的方法)都在 事务中执行
因此,@Transactional
和mySetup()
上的myTeardown()
注释有点多余,甚至可能被误导,因为它们的交易性是由当前执行的单个测试方法决定的。 / p>
这是因为beforeTestMethod()
的{{1}}和afterTestMethod()
回调(负责启动/完成事务)在JUnit的TransactionalTestExecutionListener
之前和JUnit的{{1}之后执行方法,分别。
答案 1 :(得分:6)
春天5发生了一些变化。 根据{{3}}:
方法级生命周期方法(例如,用JUnit Jupiter的 @BeforeEach 或 @AfterEach 注释的方法)在测试管理的事务中运行。
另一方面,套件级和类级生命周期方法-例如, 用JUnit Jupiter的 @BeforeAll 或 @AfterAll 注释的方法,以及用TestNG的 @BeforeSuite , @AfterSuite ,< strong> @BeforeClass 或 @AfterClass -不在测试管理的事务中运行。
如果您需要在事务内的套件级或类级生命周期方法中执行代码,则可能希望将相应的 PlatformTransactionManage r注入测试类,然后将其与用于程序化交易管理的TransactionTemplate 。
答案 2 :(得分:1)
如果使用@Transactional注释@Before和@After方法,则它们将不会在事务中运行。但是,如果将@Transactional用于测试方法(对其上具有@Test的方法)或整个测试类,则每个测试方法将在不同的事务中运行,并且@Before和@After方法也将在同一事务中运行每个@Test方法的事务。有关更多说明,请参见以下两个代码段:
@Transactional
public class MyTestClass {
@Before
public void beforeTest() {
...
}
@Test
void testMethod1() {
...
}
@Test
void testMethod2() {
...
}
@After
public void afterTest() {
...
}
}
上面的代码与下面的代码完全相同地运行:
public class MyTestClass {
@Before
public void beforeTest() {
...
}
@Test
@Transactional
void testMethod1() {
...
}
@Test
@Transactional
void testMethod2() {
...
}
@After
public void afterTest() {
...
}
}
在这两个“ testMethod1”和“ testMethod2”方法的代码片段中,将存在不同的事务。而且,“ beforeMethod”和“ afterMethod”方法也将分别在每个测试方法的事务中运行。