我试图调整应用程序域模型的删除行为。假设我有国家和地区,如果国家有任何地区,则不应删除。下面将介绍其他类/配置,但下面的代码应该测试它。countryRepository.flush();
抛出了一个DataIntegrityViolationException
,正如预期的那样,但是对countryRepository.count()
的最后一次调用抛出了相同的Exception。在日志中,您可以看到它试图再次执行DELETE SQL命令。
我希望在@Transactional
上回滚这种情况,但显然它没有-也许是因为它被assertThrows
捕获了?
@SpringBootTest
@SpringBootApplication
@TestPropertySource(locations = "classpath:unit-tests.properties")
@Transactional
public class Tests {
@Autowired
private CountryRepository countryRepository;
@Autowired
private RegionRepository regionRepository;
@Test
public void preventDeleteOfUsedObjects() {
// Create objects
Country country = new Country();
country.name = "United Status";
countryRepository.save(country);
countryRepository.flush();
Region region = new Region();
region.name = "California";
region.country = country;
regionRepository.save(region);
regionRepository.flush();
// Deleting used countries should not be possible
Assertions.assertThrows(DataIntegrityViolationException.class, () -> {
countryRepository.delete(country);
countryRepository.flush();
});
Assert.assertEquals(1, countryRepository.count());
}
}
数据模型:
@Entity
@Table(name = "countries")
public class Country {
@Id
public String name;
}
@Entity
@Table(name = "regions")
public class Region {
@Id
public String name;
@ManyToOne
public Country country;
}
对应的存储库:
public interface CountryRepository extends JpaRepository<Country, String> {
}
public interface RegionRepository extends JpaRepository<Region, String> {
}
unit-tests.properties:
spring.datasource.url=jdbc:hsqldb:mem:model;sql.syntax_pgs=true
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.hsqldb.jdbcDriver
spring.jackson.default-property-inclusion=non_null
spring.jpa.hibernate.ddl-auto=create
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
logging.level.root=INFO
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/>
</parent>
<artifactId>example</artifactId>
<name>example</name>
<properties>
<maven.compiler.release>11</maven.compiler.release>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
1条答案
按热度按时间nx7onnlm1#
经过更多的实验,我发现Spring将automatically rollback all changes after completing a test method,这是我完全没有预料到的,因为我在应用程序日志中看到了SQL
INSERT
和DELETE
语句。我应该知道它们是在BEGIN TRANSACTION
之后执行的,但是不能很容易地检查结果,因为我在没有管理工具的情况下使用HSQLDB进行单元测试。我在项目中还有其他的“单元测试”(没有标记为@Transactional
,在属性文件中有一个不同的数据库连接),用于在PostgreSQL数据库中生成一些引导数据,这些数据库按预期工作,并持久化数据。所以现在我先结束测试
希望我不会愚蠢到在我的主代码中捕获
DataIntegrityViolationException
s。