成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深度揭秘JUnit5與Mockito的單元測試神秘面紗

開發 前端
在今天的學習中,我們深入研究了單元測試,并利用 Mockito 框架加強了測試的功能。通過學習如何編寫JUnit5測試以及使用Mockito模擬依賴,我們揭開了單元測試的神秘面紗,為更健壯的代碼打下了堅實的基礎。

在今天的學習中,我們將深入研究JUnit和Mockito,這是Java開發中最強大的單元測試工具之一。通過學習如何編寫清晰、高效的單元測試,我們將揭開單元測試的神秘面紗,助力你在項目中寫出更健壯的代碼。

提示: 今天的代碼是在第九天代碼的基礎上進行開發,我們將為UserController中添加更多的單元測試方法,以展示JUnit和Mockito的強大功能。

核心知識介紹:

Unit 5 的主要特性和注解:@Test:標記方法作為測試方法。@BeforeEach / @AfterEach:分別表示在每個測試方法前后運行的方法。@BeforeAll / @AfterAll:分別表示在所有測試開始之前和所有測試結束之后只運行一次的方法。@DisplayName:為測試類或測試方法定義一個自定義的顯示名稱。@Nested:表示內部類,其成員方法可以作為嵌套的測試類進行分組。@Tag:為測試方法添加標簽,可以用來過濾測試執行。@ExtendWith:用來注冊自定義擴展,例如可以用來集成 Spring TestContext Framework。@Disabled:禁用某個測試方法或類。

JUnit 5 斷言和假設:Assertions 類提供了一系列的靜態方法來聲明斷言,如 assertEquals, assertTrue, assertAll 等。Assumptions 類提供了靜態方法來聲明測試的前提條件,如 assumeTrue。Mockito 的主要特性和注解:@Mock:創建一個模擬對象。@InjectMocks:自動注入模擬對象到被測試的類中。@Spy:創建一個真實對象的包裝,可以模擬某些方法的行為。@Captor:創建一個參數捕獲器,用于捕獲方法調用的參數。

@TestMethodOrder 是一個類型級別的注解,用于指定測試類中測試方法的執行順序。它需要與 MethodOrderer 接口的實現類一起使用,JUnit 提供了幾種不同的方法排序器,如按名稱、注解、隨機等。

@Order 是一個方法級別的注解,用于指定測試方法的執行順序。當測試類上使用了 @TestMethodOrder(OrderAnnotation.class) 注解時,你可以在每個測試方法上使用 @Order 來定義它們的執行順序。

以下是一些常用的 MethodOrderer 實現:

OrderAnnotation:根據測試方法上的 @Order 注解來指定執行順序。測試方法通過 @Order 注解的值(一個整數)來定義它們的執行順序。Alphanumeric:按照測試方法名稱的字母數字順序執行。這個順序首先考慮數字,然后是字母。MethodName:按照方法名稱的字典順序(即字符串順序)執行。Random:每次執行時都按照隨機順序執行測試方法。這有助于發現由于測試方法間的依賴關系而產生的潛在問題。DisplayName:按照測試方法的顯示名稱(@DisplayName 注解指定的值)的字典順序執行。

代碼示例:

在今天的代碼示例中,我們將在昨天的基礎上進一步完善UserController的單元測試,使用JUnit和Mockito來驗證控制器層的方法是否按照預期執行。

在 pom.xml 文件增加增加測試依賴

<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.java

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模擬依賴,我們揭開了單元測試的神秘面紗,為更健壯的代碼打下了堅實的基礎。

在代碼示例中,我們創建了一個 UserControllerTest 類,使用了 Mockito 注解和特性。主要注解包括 @Mock 用于創建模擬對象,@InjectMocks 用于創建被測試類的實例并自動注入模擬對象,@Spy 用于創建 Spy 對象,@Captor 用于捕獲方法參數,以及 @RunWith(MockitoJUnitRunner.class) 用于在 JUnit 測試中運行 Mockito 測試。

通過這些注解和特性,我們能夠編寫清晰、高效的單元測試,驗證控制器層的各個方法的行為是否符合預期。其中,我們測試了獲取所有用戶、創建用戶、獲取指定ID用戶、更新用戶、刪除用戶等方法,以確保它們在不同情況下能夠正確執行。

總體而言,通過今天的學習,我們不僅深入了解了單元測試的基本原理,還學會了如何在Spring Boot項目中使用JUnit5和Mockito框架進行測試,為后續更復雜的業務邏輯和代碼改動提供了可靠的測試基礎。在接下來的學習中,我們將繼續

責任編輯:武曉燕 來源: 路條編程
相關推薦

2021-01-07 14:06:30

Spring BootJUnit5Java

2021-08-26 11:00:54

Spring BootJUnit5Java

2023-12-24 10:00:35

Java單元測試

2017-01-16 12:12:29

單元測試JUnit

2017-01-14 23:26:17

單元測試JUnit測試

2023-10-13 18:02:57

JUnitMockito關系

2017-01-14 23:42:49

單元測試框架軟件測試

2011-11-18 15:18:41

Junit單元測試Java

2011-08-11 13:02:43

Struts2Junit

2020-07-21 14:40:45

Spring Boot單元測試Java

2023-09-27 23:43:51

單元測試Spring

2021-09-17 15:54:41

深度學習機器學習人工智能

2012-02-07 09:08:50

Feed4JUnitJava

2020-04-14 10:44:01

區塊鏈滲透測試比特幣

2009-09-01 10:20:06

protected方法單元測試

2014-02-25 10:25:52

單元測試測試

2016-10-20 12:34:08

android單元測試java

2010-02-07 15:42:46

Android單元測試

2011-07-27 17:02:12

Xcode iPhone 單元測試

2022-07-04 05:59:18

KotlinJUnit5數據庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品久久国产视频 | 中文字幕一区二区三区精彩视频 | 女人夜夜春 | 中文字幕一区在线观看视频 | 一二三区在线 | 日韩久久久一区二区 | 超碰伊人久久 | 国产成人免费网站 | 国产午夜精品一区二区三区在线观看 | 中文字幕 视频一区 | 久久久久精 | 日韩精品一区二区三区中文字幕 | 久久久久久91 | 国产精品区一区二区三 | 在线色网| 91精品国产777在线观看 | 国产精品久久亚洲 | 精品国产一区二区在线 | 久久91| 激情五月激情综合网 | 成人伊人| 欧美jizzhd精品欧美巨大免费 | 精品国产亚洲一区二区三区大结局 | 国产成人99久久亚洲综合精品 | 欧美三级久久久 | 欧美精品区 | 一区二区免费 | 国产日韩一区二区三免费高清 | 99免费 | 国产精品久久久乱弄 | 96久久久久久 | 91精品国产色综合久久 | 狠狠躁18三区二区一区 | 久久精品二区 | 免费观看一级黄色录像 | 在线不卡av| 国产精品免费在线 | 91看片网| 美国黄色毛片 | 久久久久久a | 亚洲精品乱码 |