当前位置:首页 > 科技  > 软件

深度揭秘JUnit5与Mockito的单元测试神秘面纱

来源: 责编: 时间:2024-01-02 09:31:59 153观看
导读在今天的学习中,我们将深入研究JUnit和Mockito,这是Java开发中最强大的单元测试工具之一。通过学习如何编写清晰、高效的单元测试,我们将揭开单元测试的神秘面纱,助力你在项目中写出更健壮的代码。提示: 今天的代码是在第

在今天的学习中,我们将深入研究JUnit和Mockito,这是Java开发中最强大的单元测试工具之一。通过学习如何编写清晰、高效的单元测试,我们将揭开单元测试的神秘面纱,助力你在项目中写出更健壮的代码。2CV28资讯网——每日最新资讯28at.com

提示: 今天的代码是在第九天代码的基础上进行开发,我们将为UserController中添加更多的单元测试方法,以展示JUnit和Mockito的强大功能。2CV28资讯网——每日最新资讯28at.com

核心知识介绍:

Unit 5 的主要特性和注解:@Test:标记方法作为测试方法。@BeforeEach / @AfterEach:分别表示在每个测试方法前后运行的方法。@BeforeAll / @AfterAll:分别表示在所有测试开始之前和所有测试结束之后只运行一次的方法。@DisplayName:为测试类或测试方法定义一个自定义的显示名称。@Nested:表示内部类,其成员方法可以作为嵌套的测试类进行分组。@Tag:为测试方法添加标签,可以用来过滤测试执行。@ExtendWith:用来注册自定义扩展,例如可以用来集成 Spring TestContext Framework。@Disabled:禁用某个测试方法或类。2CV28资讯网——每日最新资讯28at.com

JUnit 5 断言和假设:Assertions 类提供了一系列的静态方法来声明断言,如 assertEquals, assertTrue, assertAll 等。Assumptions 类提供了静态方法来声明测试的前提条件,如 assumeTrue。Mockito 的主要特性和注解:@Mock:创建一个模拟对象。@InjectMocks:自动注入模拟对象到被测试的类中。@Spy:创建一个真实对象的包装,可以模拟某些方法的行为。@Captor:创建一个参数捕获器,用于捕获方法调用的参数。2CV28资讯网——每日最新资讯28at.com

@TestMethodOrder 是一个类型级别的注解,用于指定测试类中测试方法的执行顺序。它需要与 MethodOrderer 接口的实现类一起使用,JUnit 提供了几种不同的方法排序器,如按名称、注解、随机等。2CV28资讯网——每日最新资讯28at.com

@Order 是一个方法级别的注解,用于指定测试方法的执行顺序。当测试类上使用了 @TestMethodOrder(OrderAnnotation.class) 注解时,你可以在每个测试方法上使用 @Order 来定义它们的执行顺序。2CV28资讯网——每日最新资讯28at.com

以下是一些常用的 MethodOrderer 实现:2CV28资讯网——每日最新资讯28at.com

OrderAnnotation:根据测试方法上的 @Order 注解来指定执行顺序。测试方法通过 @Order 注解的值(一个整数)来定义它们的执行顺序。Alphanumeric:按照测试方法名称的字母数字顺序执行。这个顺序首先考虑数字,然后是字母。MethodName:按照方法名称的字典顺序(即字符串顺序)执行。Random:每次执行时都按照随机顺序执行测试方法。这有助于发现由于测试方法间的依赖关系而产生的潜在问题。DisplayName:按照测试方法的显示名称(@DisplayName 注解指定的值)的字典顺序执行。2CV28资讯网——每日最新资讯28at.com

代码示例:

在今天的代码示例中,我们将在昨天的基础上进一步完善UserController的单元测试,使用JUnit和Mockito来验证控制器层的方法是否按照预期执行。2CV28资讯网——每日最新资讯28at.com

在 pom.xml 文件增加增加测试依赖2CV28资讯网——每日最新资讯28at.com

<dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-starter-test</artifactId>      <version>3.1.6</version>      <!-- 排除 JUnit 4 -->      <exclusions>          <exclusion>              <groupId>org.junit.vintage</groupId>              <artifactId>junit-vintage-engine</artifactId>          </exclusion>      </exclusions>  </dependency>  <dependency>      <groupId>org.hamcrest</groupId>      <artifactId>hamcrest</artifactId>      <version>2.2</version>  </dependency>

UserControllerTest.java2CV28资讯网——每日最新资讯28at.com

package com.icoderoad.springboot60days.day9.controller;import static org.hamcrest.Matchers.hasSize;import static org.hamcrest.Matchers.is;import static org.mockito.Mockito.*;import static org.mockito.ArgumentMatchers.any;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;import com.fasterxml.jackson.databind.ObjectMapper;import com.icoderoad.springboot60days.day9.entity.User;import com.icoderoad.springboot60days.day9.service.UserService;import org.junit.jupiter.api.*;import org.junit.jupiter.api.extension.ExtendWith;import org.mockito.InjectMocks;import org.mockito.Mock;import org.mockito.junit.jupiter.MockitoExtension;import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;import org.springframework.http.MediaType;import org.springframework.test.web.servlet.MockMvc;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.mock.mockito.MockBean;import java.util.Arrays;import java.util.List;@ExtendWith(MockitoExtension.class)@WebMvcTest(UserController.class)@TestMethodOrder(MethodOrderer.OrderAnnotation.class)public class UserControllerTest {    @Autowired    private MockMvc mockMvc;    @MockBean    private UserService userService;    @Autowired    private ObjectMapper objectMapper;    private User user;    @BeforeEach    void setUp() {        user = new User();        user.setId(1L);        user.setUsername("Test User");        user.setEmail("test@example.com");    }   /**     * 验证UserController的getAllUsers方法正常获取所有用户信息。     */    @Test    @Order(4)    public void getAllUsersTest() throws Exception {        List<User> users = Arrays.asList(user);        when(userService.list()).thenReturn(users);        mockMvc.perform(get("/users"))                .andExpect(status().isOk())                .andExpect(jsonPath("$", hasSize(1)))                .andExpect(jsonPath("$[0].username", is(user.getUsername())));    }   /**     * 验证UserController的createUser方法正常创建用户。     */    @Test    @Order(1)    public void createUserTest() throws Exception {        when(userService.saveOrUpdate(any(User.class))).thenReturn(true);;        mockMvc.perform(post("/users")                        .contentType(MediaType.APPLICATION_JSON)                        .content(objectMapper.writeValueAsString(user)))                .andExpect(status().isOk());        verify(userService, times(1)).save(any(User.class));    }   /**     * 验证UserController的getUserById方法正常获取指定ID的用户信息。     */    @Test    @Order(2)    public void getUserByIdTest() throws Exception {        when(userService.getById(user.getId())).thenReturn(user);        mockMvc.perform(get("/users/{id}", user.getId()))                .andExpect(status().isOk())                .andExpect(jsonPath("$.username", is(user.getUsername())));    }          /**     * 验证UserController的updateUserById方法正常更新指定ID的用户信息。     */    @Test    @Order(3)    public void updateUserByIdTest() throws Exception {      when(userService.saveOrUpdate(any(User.class))).thenReturn(true);;        mockMvc.perform(put("/users/{id}", user.getId())                        .contentType(MediaType.APPLICATION_JSON)                        .content(objectMapper.writeValueAsString(user)))                .andExpect(status().isOk());        verify(userService, times(1)).updateById(any(User.class));    }          /**     * 验证UserController的deleteUserById方法正常删除指定ID的用户。     */    @Test    @Order(5)    public void deleteUserByIdTest() throws Exception {      when(userService.removeById(user.getId())).thenReturn(true);;        mockMvc.perform(delete("/users/{id}", user.getId()))                .andExpect(status().isOk());        verify(userService, times(1)).removeById(user.getId());    }}

当天学习知识总结:

在今天的学习中,我们深入研究了单元测试,并利用 Mockito 框架加强了测试的功能。通过学习如何编写JUnit5测试以及使用Mockito模拟依赖,我们揭开了单元测试的神秘面纱,为更健壮的代码打下了坚实的基础。2CV28资讯网——每日最新资讯28at.com

在代码示例中,我们创建了一个 UserControllerTest 类,使用了 Mockito 注解和特性。主要注解包括 @Mock 用于创建模拟对象,@InjectMocks 用于创建被测试类的实例并自动注入模拟对象,@Spy 用于创建 Spy 对象,@Captor 用于捕获方法参数,以及 @RunWith(MockitoJUnitRunner.class) 用于在 JUnit 测试中运行 Mockito 测试。2CV28资讯网——每日最新资讯28at.com

通过这些注解和特性,我们能够编写清晰、高效的单元测试,验证控制器层的各个方法的行为是否符合预期。其中,我们测试了获取所有用户、创建用户、获取指定ID用户、更新用户、删除用户等方法,以确保它们在不同情况下能够正确执行。2CV28资讯网——每日最新资讯28at.com

总体而言,通过今天的学习,我们不仅深入了解了单元测试的基本原理,还学会了如何在Spring Boot项目中使用JUnit5和Mockito框架进行测试,为后续更复杂的业务逻辑和代码改动提供了可靠的测试基础。在接下来的学习中,我们将继续2CV28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-55350-0.html深度揭秘JUnit5与Mockito的单元测试神秘面纱

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 17个有用的CLI命令,作为前端工程师,你需要知道一下

下一篇: 17个有用的CLI命令,作为前端工程师,你需要知道一下

标签:
  • 热门焦点
  • 从 Pulsar Client 的原理到它的监控面板

    从 Pulsar Client 的原理到它的监控面板

    背景前段时间业务团队偶尔会碰到一些 Pulsar 使用的问题,比如消息阻塞不消费了、生产者消息发送缓慢等各种问题。虽然我们有个监控页面可以根据 topic 维度查看他的发送状态,
  • 分布式系统中的CAP理论,面试必问,你理解了嘛?

    分布式系统中的CAP理论,面试必问,你理解了嘛?

    对于刚刚接触分布式系统的小伙伴们来说,一提起分布式系统,就感觉高大上,深不可测。而且看了很多书和视频还是一脸懵逼。这篇文章主要使用大白话的方式,带你理解一下分布式系统
  • 三言两语说透柯里化和反柯里化

    三言两语说透柯里化和反柯里化

    JavaScript中的柯里化(Currying)和反柯里化(Uncurrying)是两种很有用的技术,可以帮助我们写出更加优雅、泛用的函数。本文将首先介绍柯里化和反柯里化的概念、实现原理和应用
  • 小红书1周涨粉49W+,我总结了小白可以用的N条涨粉笔记

    小红书1周涨粉49W+,我总结了小白可以用的N条涨粉笔记

    作者:黄河懂运营一条性教育视频,被54万人&ldquo;珍藏&rdquo;是什么体验?最近,情感博主@公主是用鲜花做的,火了!仅仅凭借一条视频,光小红书就有超过128万人,为她疯狂点赞!更疯狂的是,这
  • 2023年,我眼中的字节跳动

    2023年,我眼中的字节跳动

    此时此刻(2023年7月),字节跳动从未上市,也从未公布过任何官方的上市计划;但是这并不妨碍它成为中国最受关注的互联网公司之一。从2016-17年的抖音强势崛起,到2018年的&ldquo;头腾
  • 自律,给不了Keep自由!

    自律,给不了Keep自由!

    来源 | 互联网品牌官作者 | 李大为编排 | 又耳 审核 | 谷晓辉自律能不能给用户自由暂时不好说,但大概率不能给Keep自由。近日,全球最大的在线健身平台Keep正式登陆港交所,努力
  • 三星获批量产iPhone 15全系屏幕:苹果史上最惊艳直屏

    三星获批量产iPhone 15全系屏幕:苹果史上最惊艳直屏

    按照惯例,苹果将继续在今年9月举办一年一度的秋季新品发布会,有传言称发布会将于9月12日举行,届时全新的iPhone 15系列将正式与大家见面,不出意外的话
  • AI芯片初创公司Tenstorrent获三星和现代1亿美元投资

    AI芯片初创公司Tenstorrent获三星和现代1亿美元投资

    Tenstorrent是一家由芯片行业资深人士Jim Keller领导的加拿大初创公司,专注于开发人工智能芯片,该公司周三表示,已经从现代汽车集团和三星投资基金等
  • 三星显示已开始为AR设备研发硅基LED微显示屏

    三星显示已开始为AR设备研发硅基LED微显示屏

    7月18日消息,据外媒报道,随着苹果首款头显产品Vision Pro在6月份正式推出,AR/VR/MR等头显产品也就将成为各大公司下一个重要的竞争领域,对显示屏这一关
Top