【问题标题】:Testing Web Layer when Validation occurs in Service layer - Spring Boot Testing在服务层发生验证时测试 Web 层 - Spring Boot 测试
【发布时间】:2021-03-26 07:22:12
【问题描述】:

我正在为使用 Spring Boot 的项目编写测试。它是一个简单的 REST API,具有典型的 Controller-Service-Repository 结构。

我最近阅读了很多关于如何正确编写单元测试的文章。

我读过的一篇文章是这样的:
https://medium.com/blog-quiqua/https-medium-com-blog-quiqua-unit-testing-your-api-controllers-879dbf01796f

作者陈述了我目前在项目中面临的一些问题。

在我的项目中,在“Web 层” 中,我们进行了一些安全检查(主要是验证 Bearer 令牌),然后将传入的 DTO 传递给 “服务层” 然后负责验证它并在验证失败时抛出异常。

我的问题很简单: 当 ValidationException - 带有 @ResponseStatus(BAD_REQUEST) 注释的 - 是从 “服务层” 抛出的?

我是不是想太多了,这些测试应该只是集成测试而不是单元测试?

谢谢。

编辑:

简单的答案是在调用Service方法时使用Mockito,抛出ValidationException,然后检查响应状态码。

但是还有另一个问题。如果我有一个名为 EntityDTO 的实体,它的 name 属性具有任意最大长度验证。

当超过长度时,Service 会抛出带有自定义消息的 ValidationException(即“名称属性最大长度为 X”)。

如果我的 ValidationException 是通用的(在任何验证失败时抛出),我不是在“按应有的方式”进行测试,对吗?至少这是我的感觉……

编辑 2:

将问题标记为已回答。 控制器测试不应该测试太多逻辑,所以如果我只测试就可以了:

如果请求正常

如果请求以任何方式无效,则为错误请求

如果未找到,则为 NOT FOUND

等等……

如果我需要在验证失败时测试错误消息,那么回答我的最后一个问题,那就是 Web 服务层的集成测试。

【问题讨论】:

    标签: java spring spring-boot unit-testing spring-mvc


    【解决方案1】:

    将服务作为 Bean 注入(例如,将其标记为组件)并在测试中模拟它。然后让 mock 发出 ValidationException 并在 Controller 上断言以返回状态代码 400。如果不知道控制器的外观,我无法告诉你如何准确地做到这一点,因为有几种方法可以处理响应。

    【讨论】:

    • 嘿,埃里克,感谢您的快速回答!我忘了我能做到!现在就试试吧!
    • 测试是绿色的!谢谢 Eric,我不知道如何从模拟中抛出异常。
    • 现在,如果我模拟对 service.createEntity(EntityDTO body) 的每个调用以引发 ValidationException,当我传递给 Service 模拟的 EntityDTO 有任何错误时,我不能指望得到真正的 ValidationException .例如,EntityDTO 具有最大长度的名称属性。如果超过,服务会抛出 ValidationException。如果我的异常是通用的(对于任何类型的验证失败)我不是在测试“应该是”对吗?
    • 这取决于您想详细了解测试的程度。如果您只想确保将任何类型的 ValidationException 转换为 Bad Request,那么这就足够了。由于 Controller 通常只应在域/服务层和 Web 之间进行映射,因此除了返回(映射)结果并将域异常转换为适当的错误响应之外,它不应包含大量逻辑。
    • 谢谢埃里克。我认为我的问题更多是关于了解我需要测试什么,而不是关于如何测试它,请参阅原始问题的愚蠢答案。将其标记为正确答案。
    猜你喜欢
    • 2021-09-23
    • 2018-04-27
    • 1970-01-01
    • 2020-02-10
    • 2020-08-20
    • 2018-06-28
    • 2021-03-19
    • 2012-01-25
    • 2013-03-04
    相关资源
    最近更新 更多