精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深度揭秘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

2017-01-16 12:12:29

單元測試JUnit

2017-01-14 23:26:17

單元測試JUnit測試

2023-12-24 10:00:35

Java單元測試

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

2012-02-07 09:08:50

Feed4JUnitJava

2021-09-17 15:54:41

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

2009-09-01 10:20:06

protected方法單元測試

2014-02-25 10:25:52

單元測試測試

2020-04-14 10:44:01

區塊鏈滲透測試比特幣

2011-07-27 17:02:12

Xcode iPhone 單元測試

2010-02-07 15:42:46

Android單元測試

2016-10-20 12:34:08

android單元測試java

2022-07-04 05:59:18

KotlinJUnit5數據庫
點贊
收藏

51CTO技術棧公眾號

成人在线视频一区二区| 人妖一区二区三区| 国产精品福利一区| 亚洲xxx大片| 日韩精品久久久久久久酒店| 国产成人av| 欧美日韩高清一区二区三区| 久久99久久99精品| 第一页在线观看| 国产一区二区免费看| 色综合久久88| 亚洲国产日韩一区无码精品久久久| 欧美黄色网络| 亚洲国产精品久久一线不卡| 少妇精品久久久久久久久久| 国产高清视频免费观看| 久久精品导航| 欧美成人在线网站| 91精品人妻一区二区三区蜜桃欧美| 久久久久黄色| 天天av天天翘天天综合网 | 最新不卡av在线| 久久国产精品 国产精品| 一级片视频网站| 国产精品久久久久久久免费软件| 久久久久北条麻妃免费看| 久久丫精品国产亚洲av不卡| 精品99re| 欧美在线观看视频在线| 亚洲 自拍 另类小说综合图区| 尤物视频在线免费观看| 91在线精品一区二区| 18成人在线| 一级爱爱免费视频| 久久黄色影院| 国产91成人video| 久久久久久久久97| 亚洲欧洲美洲一区二区三区| 亚洲欧美日韩国产成人| 无码人妻精品一区二区三| www欧美在线观看| 欧美日韩高清一区二区三区| 天天爽天天爽夜夜爽| av资源亚洲| 午夜欧美大尺度福利影院在线看| 国产系列第一页| 超碰免费在线| 亚洲国产精品t66y| 日本在线免费观看一区| 日韩欧美亚洲系列| 972aa.com艺术欧美| 国产精品国产精品| 男人天堂av网| 99视频一区二区| 国产原创精品| 天堂在线视频免费观看| 99久久国产综合精品麻豆| 99精彩视频| 亚洲精品国产一区二| 国产91富婆露脸刺激对白| 精品成人在线| 欧美二区在线观看| 亚洲午夜激情影院| 成人在线啊v| 日韩视频一区二区在线观看| 免费看三级黄色片| 豆花视频一区二区| 亚洲国产精品专区久久| 亚洲欧美日本一区| 中国av一区| 伊人伊成久久人综合网站| 久久久久无码精品国产sm果冻| 国产午夜一区| 久久精品最新地址| 精品小视频在线观看| 一级成人国产| 国产999视频| 中文字幕第315页| 国内成+人亚洲+欧美+综合在线| 91精品中文在线| 亚洲精品国产精品国| 91麻豆国产在线观看| 区一区二区三区中文字幕| 成黄免费在线| 一区二区三区四区中文字幕| 黄色国产一级视频| 久久91导航| 日韩午夜激情av| 538国产视频| 国产精品中文字幕亚洲欧美| 日韩视频亚洲视频| 国产精品白浆一区二小说| 国产一区二区精品| 国产有码一区二区| 丰满少妇一级片| 国产亚洲成年网址在线观看| 亚洲一区高清| 精品人人视频| 欧美日韩免费一区二区三区视频| av在线天堂网| 精品国产乱码久久久久久蜜坠欲下| 久久精品国产一区二区电影| 国产真实的和子乱拍在线观看| 老司机午夜免费精品视频| 91人成网站www| 日韩电影在线观看完整版| 国产精品精品国产色婷婷| 成人毛片一区二区| 伊人久久大香| 亚洲女人天堂成人av在线| 日本 欧美 国产| 午夜宅男久久久| 国产日韩欧美在线看| 秋霞av鲁丝片一区二区| 中文字幕在线不卡视频| 久在线观看视频| 先锋影音一区二区| 亚洲网站在线观看| 五月天综合在线| 狠狠色2019综合网| 欧美一级二级三级九九九| 肉体视频在线| 欧美老肥妇做.爰bbww| 黑人巨大精品欧美| 国产综合精品| 91免费高清视频| av福利精品| 欧美视频中文在线看| 欧美国产在线一区| 99九九热只有国产精品| 欧美在线激情视频| 蜜臀av午夜精品| 亚洲黄色片在线观看| 日本高清久久久| 精品黄色一级片| 日本91av在线播放| 欧美自拍第一页| 亚洲国产一区二区a毛片| 亚洲黄色片免费看| 色999国产精品| 国产精品老女人视频| 四虎在线免费观看| 亚洲aaa精品| 亚洲视频 中文字幕| 欧美粗暴jizz性欧美20| 成人黄色片网站| 黄色在线观看网站| 欧美精品三级在线观看| 丰满的亚洲女人毛茸茸| 日产欧产美韩系列久久99| 欧洲亚洲一区| 天堂久久午夜av| 中日韩美女免费视频网站在线观看 | 欧美激情一区二区久久久| 国产一区二区三区视频免费观看| 国产精品私房写真福利视频| 91极品尤物在线播放国产| 欧美午夜精品一区二区三区电影| 国产精品jizz在线观看麻豆| 黄色网址在线播放| 欧美性猛交xxxxxxxx| 国产亚洲精品精品精品| 免费看欧美女人艹b| 亚洲午夜精品久久久久久浪潮| 久久精品 人人爱| 另类视频在线观看| 欧美亚洲精品在线观看| 欧美日韩国产在线看| 精品少妇一区二区三区免费观| 天使萌一区二区三区免费观看| 日本一区二区三区免费看| 岛国精品在线| 久久福利网址导航| 欧美一级视频免费| 欧美性xxxxxxx| jizz18女人高潮| 国产精品一区二区视频| 国产高清av在线播放| 欧美日韩播放| 成人免费视频a| 99色在线观看| 国产亚洲欧美一区| 国产高潮在线观看| 天天综合天天综合色| 又色又爽的视频| 成人性生交大片免费看视频在线| 黑人糟蹋人妻hd中文字幕 | 亚洲三级黄色在线观看| 亚洲天堂2021av| 亚洲午夜免费福利视频| 91国模少妇一区二区三区| 久久精品久久综合| 免费拍拍拍网站| 精品免费在线| 亚洲自拍偷拍一区| 电影一区二区三| 久久久久999| 久青青在线观看视频国产| 6080yy午夜一二三区久久| 国产在线综合网| 中文字幕不卡在线观看| 黄色性视频网站| 青青草91视频| 毛片在线播放视频| 一区二区蜜桃| 日韩欧美在线电影| 久久99成人| 国产精品久久久久久亚洲调教| 男人添女人下部高潮视频在线观看| 亚洲热线99精品视频| 亚洲黄色在线观看视频| 欧美偷拍一区二区| 永久免费看片在线播放| 亚洲欧美一区二区三区极速播放| 李宗瑞91在线正在播放| 高清免费成人av| 奇米视频7777| 青青国产91久久久久久 | 日韩av一区二| 2018国产在线| 欧美天堂亚洲电影院在线观看| 日韩.欧美.亚洲| 亚洲成人一品| 国产精品久久7| 日韩精品中文字幕一区二区| 国产精品免费在线免费| 在线看片国产福利你懂的| 久久99久久99精品免观看粉嫩| 在线观看的av| 国产一区二区欧美日韩| 无码国精品一区二区免费蜜桃| 日韩午夜电影av| 国产视频在线观看免费| 欧美日韩激情一区二区| 日批视频免费观看| 色综合色狠狠天天综合色| 亚洲精品视频在线观看免费视频| 亚洲综合一区二区精品导航| 国产精品视频一区二区三| 国产精品久久久久一区| 日本精品久久久久中文| 中文字幕乱码亚洲精品一区| 超碰97人人干| 久久精品亚洲精品国产欧美| av无码av天天av天天爽| av成人免费在线| 男人的天堂影院| 成人看片黄a免费看在线| 中文字幕永久免费| 成人丝袜高跟foot| 涩视频在线观看| 丁香另类激情小说| 9191在线视频| 丁香啪啪综合成人亚洲小说| 日韩女优在线视频| jizz一区二区| 能免费看av的网站| 国产亚洲精品福利| 俄罗斯毛片基地| 国产精品美女久久福利网站| 少妇太紧太爽又黄又硬又爽小说| 国产拍欧美日韩视频二区| 精品日韩在线视频| 亚洲欧美综合网| 国产精品成人免费观看| 一区二区三区在线不卡| 国产大片aaa| 日韩欧美国产免费播放| 免费av中文字幕| 欧美日韩国产大片| 国产美女自慰在线观看| 欧美大片在线观看一区二区| 成人久久久精品国产乱码一区二区| 亚洲成人黄色网| 日本午夜在线| 日韩在线精品一区| 在线三级电影| 欧美一区亚洲一区| 日韩精品第二页| 国产亚洲情侣一区二区无| 国产精品一区二区99| 中文字幕一区二区三区在线乱码| 韩日在线一区| 精品国产成人av在线免| 久久国产精品第一页| 无码人妻aⅴ一区二区三区玉蒲团| 91亚洲精品久久久蜜桃网站| 亚洲第一综合网| 亚洲欧美国产毛片在线| 91美女免费看| 欧美精品丝袜中出| 欧美一区二不卡视频| 伊人精品在线观看| 中文字幕伦理免费在线视频| 69av在线播放| 91麻豆精品国产综合久久久| 国产美女精品久久久| 精品视频国产| 国产freexxxx性播放麻豆| 日本不卡视频在线观看| 国产精品嫩草69影院| 国产女人aaa级久久久级| 欧美人妻一区二区| 色伊人久久综合中文字幕| 精品人妻一区二区三区含羞草| 亚洲欧美国产一本综合首页| 操你啦视频在线| 国产99久久精品一区二区| 91精品久久久久久综合五月天 | 国产一线在线观看| 国产精品网站一区| 91香蕉在线视频| 欧美高清dvd| 精品无吗乱吗av国产爱色| 欧美精品videos另类日本| 国产成人精品一区二区三区视频 | 国产精品视频xxx| 国产精品99久久免费观看| 国产卡一卡二在线| 男人操女人的视频在线观看欧美| 久久久久9999| 亚洲综合精品久久| 国产原创中文av| 一本大道亚洲视频| av资源亚洲| 久久久com| 亚洲另类黄色| 岛国av免费观看| 夜夜嗨av一区二区三区| 亚洲在线视频播放| 亚洲性视频网站| 黄色成人免费网| 久久99国产精品99久久| 精品二区久久| 337p日本欧洲亚洲大胆张筱雨| 国产精品第13页| 中文字幕+乱码+中文乱码91| 亚洲天堂av网| 黄色成人免费网| 免费观看成人在线| 亚洲欧美日本日韩| 国产麻豆天美果冻无码视频| 黄色成人在线免费| 色呦呦视频在线| 91国自产精品中文字幕亚洲| 国产伦精品一区二区三区免费优势 | 欧美国产专区| 三大队在线观看| 亚洲成在人线在线播放| 亚洲奶汁xxxx哺乳期| 欧美激情一区二区三区久久久| 久久国产精品美女| 粉嫩av一区二区三区天美传媒| 国内成人精品2018免费看| 国产97免费视频| 日韩欧美国产一区二区在线播放| 2024最新电影在线免费观看| 亚洲伊人久久大香线蕉av| 亚洲乱码精品| 国产a级片视频| 亚洲国产aⅴ天堂久久| 欧美一区二区公司| 欧美一性一乱一交一视频| 国产精品欧美三级在线观看| 777米奇影视第四色| 欧美国产精品久久| 国产又粗又大又爽| 欧美黄色三级网站| 欧美三级电影在线| 青青在线视频观看| 国产精品色婷婷久久58| 国产精品亚洲欧美在线播放| 欧美片一区二区三区| 欧美有码在线| 无码人妻精品一区二区三区66| 中文字幕va一区二区三区| 国产又粗又猛又黄又爽无遮挡| 欧美刺激性大交免费视频| 国内精品免费| 日韩免费高清在线| ...xxx性欧美| 无码国产精品高潮久久99| 国产精品成人av性教育| 亚洲h色精品| 国产性生活毛片| 欧美日韩在线综合| 日皮视频在线观看| 日本成人黄色| 国产美女在线观看一区| 波多野结衣国产| 久久精品免费播放| 图片婷婷一区| 欧美成人手机在线视频| 大伊人狠狠躁夜夜躁av一区 | 欧美xxxx14xxxxx性爽| 天堂av一区二区三区在线播放| 香港日本韩国三级网站| 亚洲国产你懂的| 欧美极品jizzhd欧美仙踪林| 不卡视频在线播放|