利用@WebMvcTest测试Spring MVC应用

文章目录
    1. @WebMvcTest概述
    1. 创建Spring Boot项目
    1. 创建主页控制器类
    1. 准备图片素材
    1. 创建主页模板视图
    1. 主页控制器测试类
    • 6.1 创建主页控制器测试类
    • 6.2 运行单元测试方法
    1. 启动应用,查看结果
    • 7.1 启动应用
    • 7.2 访问项目首页
    1. 实战小结

1. @WebMvcTest概述

  • 在 Spring MVC 应用的测试领域,@WebMvcTest 注解发挥着极为关键的作用。它为测试提供了专门定制的 Spring 环境支持,使得开发者能够在无需完整启动应用服务器的情况下,对 Spring MVC 的核心功能进行精准测试。

  • 传统的测试方式可能需要启动整个服务器来验证功能,这种做法在某些场景下显得笨重且效率低下。而 @WebMvcTest 则不同,它专注于 Spring MVC 相关的组件,例如控制器(Controller)等。通过注入 MockMvc 实例,测试类能够轻松地模拟 Spring MVC 的运行机制。

  • MockMvc 为测试带来了极大的便利性。它允许开发者编写测试用例来模拟 HTTP 请求的发送与接收,就如同在真实的浏览器与服务器交互环境中一样。例如,可以轻松地模拟 GET、POST 等各种 HTTP 方法的请求,并且对控制器返回的结果进行断言验证。这意味着能够快速地检查控制器中的业务逻辑是否正确,比如验证数据是否被正确处理、视图是否正确返回等。

  • 在实际应用场景中,假设我们正在开发一个电商系统的商品控制器。使用 @WebMvcTest 注解的测试类可以注入 MockMvc,并针对商品的查询、添加、修改等操作编写详细的测试用例。如模拟一个查询商品列表的 GET 请求,然后验证返回的商品数据是否符合预期,包括商品的名称、价格、库存等信息是否准确无误。如果没有 @WebMvcTest 提供的这种简洁高效的测试机制,开发者可能需要花费大量精力启动整个电商应用服务器,进行复杂的端到端测试,这不仅耗时,而且在开发初期可能由于其他模块尚未完善而难以开展。

  • 综上所述,@WebMvcTest 注解在 Spring MVC 应用测试中具有不可替代的地位。它通过巧妙地注入 MockMvc,以轻量级的方式模拟 Spring MVC 运行机制,极大地提高了测试效率,让开发者能够更加专注于控制器层逻辑的正确性验证,从而加速整个 Spring MVC 应用的开发与完善进程。

2. 创建Spring Boot项目

  • 设置项目基本信息
  • 选择Spring Boot版本,添加项目依赖
  • 单击【Create】按钮,生成项目基本骨架

3. 创建主页控制器类

  • net.huawei.tacocloud包里创建controller子包

  • controller子包里创建HomeController

    package net.huawei.tacocloud.controller;

    /**

    • 功能:主页控制器
    • 作者:华卫
    • 日期:2024年12月02日
      */

    import org.springframework.stereotype.Controller;

    import org.springframework.web.bind.annotation.GetMapping;

    @Controller // 控制器注解

    public class HomeController {

    @GetMapping("/") // 处理对根路径"/ "的请求

    public String home() {

    return "home"; // 返回逻辑视图名

    }

    }

  • 可以看到,这个类带有@Controller注解。就其本身而言,@Controller并没有做太多的事情。它的主要目的是让组件扫描将这个类识别为一个组件。因为HomeController带有@Controller注解,所以Spring的组件扫描功能会自动发现它,并创建一个HomeController实例作为Spring应用上下文中的bean。

  • 实际上,有一些其他的注解与@Controller有着类似的目的(包括@Component@Service@Repository)。你可以为HomeController添加上述的任意其他注解,其作用是完全相同的。但是,在这里选择使用@Controller更能描述这个组件在应用中的角色。

  • home()是一个简单的控制器方法。它带有@GetMapping注解,表明如果针对"/"发送HTTP GET请求,那么将会由这个方法来处理请求。该方法所做的只是返回String类型的home值。

  • 这个值将会解析为视图的逻辑名。视图如何实现取决于多个因素,但是Thymeleaf位于类路径中,使得我们可以使用Thymeleaf来定义模板。

4. 准备图片素材

  • static里创建images目录
  • 将图片TacoCloud.png拷贝到images目录

5. 创建主页模板视图

  • templates里创建home.html文件

    Taco Cloud Home

    Welcome to Taco Cloud

  • 这个模板并没有太多需要讨论的。唯一需要注意的是用于展现Taco Cloud Logo的<img>标签。它使用了Thymeleaf的th:src属性和@{...}表达式,以便于引用相对于上下文路径的图片。除此之外,这个主页就是一个扮演"Hello World"角色的页面。

6. 主页控制器测试类

6.1 创建主页控制器测试类

  • testjavanet.huawei.tacocloud包里创建HomeControllerTest

    package net.huawei.tacocloud;

    import net.huawei.tacocloud.controller.HomeController;

    import org.junit.jupiter.api.Test;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;

    import org.springframework.test.web.servlet.MockMvc;

    import static org.hamcrest.Matchers.containsString;

    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;

    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

    /**

    • 功能:主页控制器测试类

    • 作者:华卫

    • 日期:2024年12月02日

      */

      @WebMvcTest(HomeController.class) //针对HomeController的Web测试

      public class HomeControllerTest {

      @Autowired

      private MockMvc mockMvc; // 注入MockMvc

      @Test

      public void testHomePage() throws Exception {

      mockMvc.perform(get("/")) // 发起对"/"的GET请求

      .andExpect(status().isOk()) // 期望得到HTTP 200

      .andExpect(view().name("home")) // 期望得到home视图

      .andExpect(content().string(containsString("Welcome to Taco Cloud"))); // 期望包含"Welcome to Taco Cloud"

      }

      }

  • 对于这个测试,首先注意到的可能就是它使用了与TacoCloudApplicationTests类不同的注解。HomeControllerTest没有使用@SpringBootTest标记,而是添加了@WebMvcTest注解。这是Spring Boot提供的一个特殊测试注解,让这个测试在Spring MVC应用的上下文中执行。更具体来讲,在本例中,它会将HomeController注册到Spring MVC中,这样一来,我们就可以向它发送请求了。

  • @WebMvcTest同样会为测试Spring MVC应用提供了Spring环境的支持。尽管可以启动一个服务器来进行测试,但是对于我们的场景来说,仿造一下Spring MVC的运行机制就可以。测试类被注入了一个MockMvc,能够让测试实现mockup。

  • 通过testHomePage()方法,我们定义了针对主页想要执行的测试。它首先使用MockMvc对象对"/"(根路径)发起HTTP GET请求。对于这个请求,我们设置了如下的预期:

    • 响应应该具备HTTP 200 (OK)状态
    • 视图的逻辑名称应该是home
    • 渲染后的视图应该包含文本Welcome to Taco Cloud

6.2 运行单元测试方法

  • 运行testHomePage()测试方法,查看结果

  • 如果在MockMvc对象发送请求之后,上述预期没有全部满足,那么这个测试会失败。但是,我们的控制器和视图模板在编写时都满足了这些预期,所以测试应该能够通过,并且带有成功的图标------至少能够看到一些绿色的背景,表明测试通过了。

  • 解决Mockito警告:Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build what is described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#0.3

  • Mockito 目前使用 Java Agent 来启用其内联模拟制造器。在未来的 JDK 版本中,这种动态附加可能不再工作。为了解决这个问题,你需要按照 Mockito 的文档配置 Mockito 作为构建过程中的 Agent。根据 Mockito 的文档,在Maven构建配置中添加插件。

    org.apache.maven.plugins maven-surefire-plugin 3.5.2 -javaagent:"${settings.localRepository}/org/mockito/mockito-core/5.14.2/mockito-core-5.14.2.jar"

  • 再次运行testHomePage()测试方法,查看结果

7. 启动应用,查看结果

7.1 启动应用

  • 运行引导类TacoCloudApplication

7.2 访问项目首页

  • 访问http://localhost:8080

8. 实战小结

  • 在本次实战中,我们深入探讨了Spring Boot项目中@WebMvcTest注解的应用,它允许开发者在不启动整个服务器的情况下,高效测试Spring MVC组件。通过逐步指导,我们创建了Spring Boot项目,编写了主页控制器和测试类,并通过MockMvc进行了单元测试。此外,解决了Mockito的Java Agent警告,确保了测试的顺利进行。最终,我们成功启动应用并验证了测试结果,展示了@WebMvcTest在提升测试效率和专注业务逻辑验证方面的重要性。
相关推荐
Diligently_14 小时前
Anolis 系统更新与密码设置&磁盘扩容
java·后端·spring
霸道流氓气质16 小时前
Spring 事务同步机制 —— AfterTransactionActionCollector 的异步解耦原理
java·后端·spring
星空18 小时前
Springboot复习
java·spring boot·spring
树码小子20 小时前
什么是大语言模型
人工智能·语言模型·mvc
聊浮游21 小时前
JAVA2026最新全套学习资料、学习路线
java·开发语言·jvm·mysql·spring·maven·idea
未秃头的程序猿1 天前
读Spring AI源码的方法——不是硬啃,是带着问题去翻
java·后端·spring
evans在进步1 天前
Spring MVC 核心机制详解:全局异常处理、请求跳转与数据绑定
java·spring·mvc
趴下吧1 天前
spring boot启动流程总结
java·spring boot·spring
Tirzano1 天前
springoauth2server配置
java·spring boot·spring
JacksonMx1 天前
ContentCachingRequestWrapper 实战:解决请求体“只能读一次”的官方方案
java·spring boot·spring