为什么要在对控制器类进行单元测试时使用 Spring 的模拟 MVC



我看到周围的人在控制器类的单元测试中使用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的功能,而不是被测方法的实际代码?

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

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

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

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

(3) Spring 框架引发的输入验证异常(当您使用 @Valid 时)

上面的第 (1) 项是我们通常使用所有其他类(如服务、实用程序类等)进行测试的内容。

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

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

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

根据我的经验,我将尝试回答您的问题。

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

这是开发人员用来编写干净工作代码的额外检查。 干净的工作代码意味着编写的每一行都应该做它本来的样子 期望做到。你如何做到这一点?这是单元测试。这 您正在编写的独立代码单元应独立验证。 方法是代码中表示独立单元代码的最佳部分 模板。

方法的单元测试

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

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

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

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

希望这能澄清您的疑问。

最新更新