Spring手动事务管理集成测试

时间:2015-08-10 08:23:06

标签: spring transactions spring-test-dbunit

我已经阅读了许多关于使用Spring进行集成测试的帖子和帖子,但没有任何内容令人满意或有帮助。

我们将Spring 3.2.3与Hibernate,Spring Data和Oracle数据库结合使用。为了测试,我们还使用DbUnit和Spring-test-dbunit。在生产代码中,事务由控制器启动,服务本身对事务没有任何了解。

所以,这是我的测试:

@ContextConfiguration // ...
@ActiveProfiles // ...
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
    DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class,
    TransactionalTestExecutionListener.class,
    ModifiedDbUnitTestExecutionListener.class })
@DbUnitConfiguration(databaseConnection = "oracleConnection")
@DatabaseSetup("/database/snapshot/snapshot.xml")
public class IntegrationTest extends AbstractTransactionalJUnit4SpringContextTests
{
    @Test
    public void sampleTest()
    {
        // transaction is already started

        this.assertThatNewsContains(0);

        News news1 = new News();
        news1.setTitle("Test News 1");
        News savedNews1 = this.newsService.save(news1);
        Assert.assertTrue(savedNews1.getId() > 0);

        News news2 = new News();
        news2.setTitle("Test News 2");
        News savedNews2 = this.newsService.save(news2);
        Assert.assertTrue(savedNews2.getId() > 0);

        News news3 = new News();
        news3.setTitle("Test News 3");
        News savedNews3 = this.newsService.save(news3);
        Assert.assertTrue(savedNews3.getId() > 0);

        // transaction commit should occur HERE
        // @todo: HOW ?!

        this.assertThatNewsContains(3);
    }

    private void assertThatNewsContains(int newsSize)
    {
        List<News> allNews = this.newsService.getNews();
        Assert.assertEquals(newsSize, allNews.size());
    }

}

我发现,如果我用@Transactional(propagation=Propagation.REQUIRES_NEW)注释NewsService,测试工作正常,但它与生产模式不同。 @Transactional(propagation=Propagation.REQUIRED)是不够的,因为DbUnit-Spring-test自己打开一个事务,而后者断言失败,因为事务尚未提交。如何在执行最后一个断言之前实现事务的提交?

2 个答案:

答案 0 :(得分:5)

我想说明我最终是如何在单独的交易中设法执行某些代码的。

你需要

@Entity
@Table(name = "Table1")
public class Table1 {
  @Id
  @Column(name = "uid")
  public String getUid();

  @Column(name = "col1")
  public String getCol1();

  @Column(name = "col2")
  public String getCol2();

  @Column(name = "col3")
  public String getCol3();

  @Column(name = "col4")
  public String getCol4();

  @Column(name = "col5")
  public String getCol5();
}

@Entity
@Table(name = "Table2")
public class Table2 {

  @Id
  @Column(name = "uid")
  public String getUid();

  @Column(name = "col3")
  public BigDecimal getCol3();

  @Column(name = "col4")
  public String getCol4();

  @Column(name = "col5")
  public String getCol5();
}

在您的测试课程中。然后,您可以执行以下操作:

@Autowired
private PlatformTransactionManager          platformTransactionManager;

private TransactionTemplate             transactionTemplate;

答案 1 :(得分:0)

如文档中所述

http://springtestdbunit.github.io/spring-test-dbunit/

如果已将DBUnit测试配置为使用are DbUnitTestExecutionListener运行,并且还使用TransactionalTestExecutionListener,则在设置数据之前可能会遇到未启动的事务,或者在验证预期结果之前回滚的问题。为了使用DBUnit支持@Transactional测试,您应该使用 TransactionDbUnitTestExecutionListener 类。

要启动事务,您必须使用注释来测试您的测试方法或类 像这样的@Transactional注释。

@Test
@Transactional
    public void sampleTest()
    {
相关问题