我使用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.
我确信这是常见的任务。但我不知道如何优雅地解决它。
答案 0 :(得分:0)
我想我错过了一些部分,但是如何在测试中将prepareDatabase放入@Before方法。
@Before
public void setupDatabaseForEachTest(){
prepareDatabase(persistenceService);
}
我认为这样可以让@Test成为@Transactional并为您提供所需的结果。