繁体   English   中英

@Before 和 @Transactional

[英]@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM