Spring Boot测试。以编程方式初始化数据库

时间:2018-01-24 15:00:21

标签: java database spring spring-boot integration-testing

我使用Spring Boot开发WebApp。我需要与数据库进行集成测试。我在数据库启动时遇到问题。我知道可以使用initilazion scripts准备数据库。我部分地做了。但是有些记录有BLOB的类型,并且通过脚本初始化它很烦人。所以我试图使用ApplicationContext中的@Test实现从CrudRepository方法以编程方式初始化此记录(这些实现封装在PersistenceService中)。

@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
        TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class})
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DatabaseSetup(MyTest.DATASET)
@DatabaseTearDown(type = DatabaseOperation.DELETE_ALL, value = { MyTest.DATASET })
@DirtiesContext
public class MyTest {
    protected static final String DATASET = "classpath:dbunit/customer.xml";

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private PersistenceService persistenceService;

    @Test
    @Transactional
    @Rollback(false)
    public void afterGroupDeleteCrlShouldContainsAllCertificates() throws Exception {

        prepareDatabase(persistenceService);

        restTemplate.delete("/customer/");
    }

但是@Test方法标记@Transactional方法是我在调用restTemplate.delete()时遇到死锁的原因,因为存在未通信的事务。

所以我在调用prepareDatabase(persistenceService)这个片段之后尝试手动添加事务:

if (TestTransaction.isActive()) {
    TestTransaction.flagForCommit();
    TestTransaction.end();
}

此代码段修复了死锁,但在测试执行后生成了SQLException

java.sql.SQLException: PooledConnection has already been closed.

我确信这是常见的任务。但我不知道如何优雅地解决它。

1 个答案:

答案 0 :(得分:0)

我想我错过了一些部分,但是如何在测试中将prepareDatabase放入@Before方法。

@Before
public void setupDatabaseForEachTest(){
  prepareDatabase(persistenceService);
}

我认为这样可以让@Test成为@Transactional并为您提供所需的结果。