[英]@Before and @Transactional
我有
@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 会在同一个事务中运行吗? 看起来他们应该这样做,但我收到了一些奇怪的错误,这可能表明他们正在互相踩踏。
是的,所有三种方法都将在同一个事务中运行。 请参阅参考文档中的TestContext Framework/Transaction management部分:
任何 before 方法(例如用 JUnit 的 @Before 注释的方法)和任何 after 方法(例如用 JUnit 的 @After 注释的方法)在事务中执行
因此mySetup()
和myTeardown()
上的@Transactional
注释有点多余,甚至可能被认为是误导,因为它们的事务性是由当前正在执行的单个测试方法决定的。
这是因为TransactionalTestExecutionListener
(负责启动/完成事务)的beforeTestMethod()
和afterTestMethod()
回调分别在 JUnit 的@Before
之前和 JUnit 的@After
方法之后执行。
Spring 5 发生了一些变化。根据文档:
方法级生命周期方法——例如,用 JUnit Jupiter 的@BeforeEach或@AfterEach注释的方法——在测试管理的事务中运行。
另一方面,套件级和类级生命周期方法——例如,用 JUnit Jupiter 的@BeforeAll或@AfterAll注释的方法和用 TestNG 的@BeforeSuite 、 @AfterSuite 、 @BeforeClass或@AfterClass注释的方法——不在内部运行一个测试管理的事务。
如果您需要在事务中的套件级或类级生命周期方法中执行代码,您可能希望将相应的PlatformTransactionManage r 注入您的测试类,然后将其与TransactionTemplate 一起用于编程事务管理。
如果您使用@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”方法将分别在每个测试方法的事务中运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.