@Before和@Transactional

时间:2013-06-25 21:58:53

标签: java spring unit-testing junit

我有

@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都会在同一个事务中运行吗?看起来他们应该这样,但我得到一些奇怪的错误,这可能表明他们互相踩着。

3 个答案:

答案 0 :(得分:19)

是的,这三种方法都将在同一个交易中运行。请参阅参考文档中的TestContext Framework/Transaction management部分:

  

任何之前的方法(例如使用JUnit的@Before注释的方法)和任何后续方法(例如使用JUnit的@After注释的方法)都在 事务中执行

因此,@TransactionalmySetup()上的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”方法也将分别在每个测试方法的事务中运行。