我们Spring开发人员知道,如果尝试删除具有其他关联实体的实体,就会引发DataIntegrityViolationException。
我编写了一个既捕获EmptyResultDataAccessException异常又捕获DataIntegrityViolationException异常的delete方法,并为每种情况抛出自定义服务级异常:
@Service
public class CityService {
@Autowired
private CityRepository repository;
public void delete(Long id) {
try {
repository.deleteById(id); // returns 204
}
catch (EmptyResultDataAccessException e) {
throw new ResourceNotFoundException("Id not found " + id); // returns 404
}
catch (DataIntegrityViolationException e) {
throw new DatabaseException("Integrity violation"); // returns 400
}
}
}我已经全部设置好了,所以第一个场景返回204,第二个场景返回404,第三个场景返回400。当我在邮递员上测试它时,一切都很好。
但是,当我尝试使用MockMvc编写集成测试时,DataIntegrityViolationException场景无法工作!(另外两种方案起作用)。
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
public class CityControllerIT {
@Autowired
private MockMvc mockMvc;
(...)
@Test
public void deleteShouldReturnBadRequestEventWhenDependentId() throws Exception {
mockMvc.perform(delete("/cities/{id}", 1L))
.andExpect(status().isBadRequest());
}
}它是返回204而不是400!我在try块中打印了一些消息,我发现它实际上没有抛出异常。try块完全执行,因为不存在完整性冲突。
@Service
public class CityService {
@Autowired
private CityRepository repository;
public void delete(Long id) {
try {
System.out.println("START");
repository.deleteById(id);
System.out.println("FINISH");
}
(...)我缺少一些关于MockMvc基本面的东西吗?为什么在执行MockMvc测试时忽略了完整性冲突?
我在Github上保存了一个最小的h2只克隆和运行的项目:https://github.com/acenelio/mockmvc-dataintegrity
发布于 2021-05-19 13:16:10
DataIntegrityViolationException在@Transactional中不能正常工作,甚至在以下常见服务方法中也是如此:
@Service
public class MyService {
@Autowired
private MyRepository repository;
@Transactional
public void delete(Long id) {
try {
repository.deleteById(id);
}
catch (DataIntegrityViolationException e) {
// do something
}
}
}类似地,如果您想自动化测试一个DataIntegrityViolationException场景,您不应该用@Transactional注释您的测试类。
因此,如果您编写事务性集成测试(每个测试的回滚数据库),您可能希望创建另一个没有@Transactional注释的测试类来测试您的DataIntegrityViolationException场景。
https://stackoverflow.com/questions/67562331
复制相似问题