首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MockMvc不为DataIntegrityViolationException工作

MockMvc不为DataIntegrityViolationException工作
EN

Stack Overflow用户
提问于 2021-05-16 23:15:50
回答 1查看 166关注 0票数 0

我们Spring开发人员知道,如果尝试删除具有其他关联实体的实体,就会引发DataIntegrityViolationException

我编写了一个既捕获EmptyResultDataAccessException异常又捕获DataIntegrityViolationException异常的delete方法,并为每种情况抛出自定义服务级异常:

代码语言:javascript
运行
复制
@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场景无法工作!(另外两种方案起作用)。

代码语言:javascript
运行
复制
@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块完全执行,因为不存在完整性冲突。

代码语言:javascript
运行
复制
@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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-19 13:16:10

DataIntegrityViolationException@Transactional中不能正常工作,甚至在以下常见服务方法中也是如此:

代码语言:javascript
运行
复制
@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场景。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67562331

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档