【问题标题】:Why use Spring's Mock MVC when you have unit tets of your controller classes为什么在对控制器类进行单元测试时使用 Spring Mockmvc
【发布时间】:2017-03-31 10:18:40
【问题描述】:

我看到我周围的人在控制器类的单元测试中使用 Spring MVC,这对单元测试的用途没有帮助。

单元测试应该测试控制器类的实际实现,这可以通过简单的 Junit 测试而不是使用 Spring Mock MVC 更准确地实现。

但是问题来了,那么 Spring Mock MVC 的真正用途是什么?你需要它做什么?

假设我有以下代码:

@Controller
@RequestMapping("/systemusers")
public class SystemUserController
{
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String getUser(final Model model)
    {

        // some logic to return user's details as json

        return UserDetailsPage;
    }
 }

我可以用 Junit 比用 Spring Mock MVC 更准确地测试这个类/控制器(它所做的只是生成一些可以用 junit 断言的 json)。

我还可以使用 Spring Mock MVC 进行测试,例如使用正确的端点返回正确的 HTTP 状态和正确的响应页面字符串。

但这是否意味着我们正在测试 Spring MVC 的功能而不是被测方法的实际代码?

附: :我将代码保持在最低限度,我认为这足以解释我的问题。假设没有编译错误。

【问题讨论】:

  • 使用 JUnit 编写的东西并不意味着它是一个单元测试,它很可能是一个集成测试,您可以在其中测试整个设置。
  • 我看到的测试绝对不是集成测试
  • MockMvc 可以以两种不同的方式使用,独立的和完整的设置。独立模式基本上是设置控制器,然后像处理请求一样执行它。另一个好处是您还在控制器上测试您的映射,如果您只是调用该方法,您将不会对其进行测试。如果您希望发生某些事情(类型检查、自定义错误处理),这可能会非常方便。
  • 接下来,如果你真的需要一个广泛的单元测试来测试你的控制器的功能,你可能在你的控制器中做的太多了,它基本上应该只是 web 和你的服务之间的集成组件层。它应该几乎不包含任何逻辑。

标签: java spring junit mockmvc


【解决方案1】:

当涉及到Controller(或任何公开的端点)类的单元测试时,我们将验证两件事:

(1) Controller 的实际逻辑本身是独立的,即是否调用正确的服务调用等。

(2) 请求URL映射和响应状态&对象

上面的第 (1) 项是我们对所有其他类(如服务、实用程序类等)的一般测试。

需要针对已暴露的端点(控制器类)额外覆盖/测试第(2)项,因此无论我们使用 Spring 的 MockMVC 还是其他机制来做到这一点,它都是真的取决于我们。

Spring 的 MockMVC 确实可以帮助我们启动内存中的 servlet 容器并检查是否调用了正确的控制器方法,然后发出正确的响应。

根据我的个人经验,测试控制器(针对 item(2))帮助我解决了 URL 映射冲突问题(当然,在同一个控制器中)等等。而不是在后期修复它们项目。

【讨论】:

  • 增加了使用@Valid 注释和相应的返回码测试参数验证的可能性,或者检查@ExceptionHandlers 是否工作的可能性。
【解决方案2】:

根据我的经验,我会尽力回答你的问题。

首先我们需要了解为什么要使用单元测试?

这是开发人员用来编写干净的工作代码的额外检查。 干净的工作代码意味着编写的每一行都应该做它是什么 预计会做。你是怎么做到的?单元测试来了。这 您正在编写的独立代码单元应独立验证。 方法是代表独立单元代码的代码中最好的部分 模板。

方法的单元测试

开发者应该为描述方法的方法编写一个测试 行为。我遵循的可能检查是它是否返回 考虑所有积极情景的预期值?它在工作吗 例外情况?是否调用了正确的后续方法?

开发人员应该通过实际调用方法来验证该方法,并提供一个 模拟环境

以下是您问题的可能答案。尽管它完全基于开发人员。

控制器方法旨在调用正确的服务调用,接受输入并将值从服务返回到视图。 所以我可能会考虑为控制器方法编写一个单元测试用例,因为您认为这是一种正确的方法。但是您应该以与实时调用相同的方式调用该方法来验证该方法。 所以你需要像 MVC 一样调用控制器方法。因此,使用 MockMVC 是更好的选择。 MockMVC 还可用于验证作为控制器方法一部分的 url、输入参数、响应和状态。考虑到所有这些,它使它成为独立的代码单元。

希望这能澄清你的疑问。

【讨论】:

    猜你喜欢
    • 2019-07-07
    • 2014-02-08
    • 1970-01-01
    • 2017-12-06
    • 2012-05-25
    • 2014-05-31
    • 2021-03-14
    • 2015-03-29
    • 2016-11-14
    相关资源
    最近更新 更多