簡體   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