Spring Boot:测试控制器层时是不是应该测试验证

Posted

技术标签:

【中文标题】Spring Boot:测试控制器层时是不是应该测试验证【英文标题】:Spring boot: should validation been tested when testing controller layerSpring Boot:测试控制器层时是否应该测试验证 【发布时间】:2018-04-27 15:00:25 【问题描述】:

我正在从事我希望拥有良好的测试基础设施的项目。 我正在使用 spring boot,它可以更轻松地测试项目的不同层:例如

如果我想测试控制器层,我将模拟(使用 mockito)控制器的服务依赖关系,并检查是否会在给定的 http 请求上调用正确的服务方法,并返回预期的 http 状态。如果我想测试服务层,我将模拟存储库和业务逻辑依赖项。以此类推。

在我的项目中,我使用 spring 验证器来检查请求正文是否正确传递(使用 @InitBinder 方法,我将自定义验证器添加到 WebDataBinder,并使用 @Valid 注释,调用这些验证器在已解析的请求正文上)。

所以我的问题是:模拟验证器并仅测试控制器逻辑是否是一种好习惯(验证器将在验证器层的上下文中进行测试)? 我只是不确定哪个是最佳实践,同时测试验证器和控制器是否正常?

【问题讨论】:

【参考方案1】:

当您测试控制器逻辑、验证逻辑,尤其是业务逻辑时,模拟并不总是最佳选择。我不建议嘲笑其中任何一个。

您可以使用各种框架进行测试:

    控制器逻辑 - RestAssured 或 MockMvc 业务逻辑 - SpringBootTestSpringRunner 下的普通 JUnit 测试 验证逻辑 - SpringBootTest 下的普通 JUnit 测试和 SpringRunner

进一步阅读:RestAssured:http://rest-assured.io/ Spring 验证器测试:Writing JUnit tests for Spring Validator implementation

【讨论】:

我个人认为,单独测试项目层是一种很好的做法,而模拟有助于实现这一点(如果你有一个面向对象的设计,它正确地保持了“依赖倒置”的设计原则)。我同意你提到的三点。但是要测试与验证层分开的控制器层(就像您在第 1 点和第 3 点中所建议的那样),您需要模拟控制器使用的验证器,这是我的问题:“模拟验证器是否是一种好习惯单独测试控制器层?” 如果你使用 RestAssured,我的回答是不要在控制器层模拟验证器 如果我从 RestAssured 文档中理解正确的话,这种技术不仅会测试控制器层,还会测试端点下的整个逻辑,因此它将成为生产测试,而不仅仅是层的单元测试。粗略地说,我将分别进行一些生产测试,也许我会为此目的使用 RestAssured,但在此之前,我想测试独立于另一层的控制器层。如果我对您的理解正确,您甚至建议不要模拟服务,我不同意。但我猜它的个人喜好。无论如何,谢谢你的回答。 嗨 haykart,你是如何解决这个问题的?我面临同样的问题。我正在使用@WebMvcTest 测试我的应用程序Web 层。我不希望它连接到数据库,因为这样做不是单元测试。

以上是关于Spring Boot:测试控制器层时是不是应该测试验证的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot junit 测试安全应用程序

Spring Boot junit测试安全应用程序

Spring Boot Rest控制器单元测试

Springboot 热部署问题。亲测可用。

Spring Boot API 的单元测试

Spring Boot REST 应用测试方法