Springboot教程(五)——單元測試

idea中一般使用JUnit進行單元測試?

基本使用

我們可以在idea的test文件夾下的XXXXApplicationTests內進行單元測試:

可以在@Test標注的方法上寫測試代碼:?

@SpringBootTest
class C0101ApplicationTests {@Testfun contextLoads() {println("Hello World")}}

我們也可以寫多個測試方法:

@SpringBootTest
class C0101ApplicationTests {@Testfun test1() {println("test1")}@Testfun test2() {println("test2")}}

我們也可以在測試類內使用@Autowired注解,如我們可以自動注入寫好的服務:

@Autowired
lateinit var testService: TestService

我們來舉個例子,先創建一個服務:

package com.example.c0101.serviceimport org.springframework.stereotype.Service@Service
class TestService {fun check(username: String, password: String): Boolean{return username == "admin" && password == "123456"}
}

然后在測試類內使用Autowired自動注入服務,并進行測試:

package com.example.c0101import com.example.c0101.service.TestService
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest@SpringBootTest
class C0101ApplicationTests {@Autowiredlateinit var testService: TestService@Testfun test() {println(testService.check("111", "123"))println(testService.check("admin", "123456"))}}

控制臺輸出:

...
false
true
...

測前準備和測后收尾

我們可以用以下注解實現測前準備和測后收尾:

  • @BeforeEach:在每一個測試方法執行前執行,其標注的方法可以傳入一個TestInfo類型的參數,為當前測試信息的對象
  • @AfterEach:在每一個測試方法執行后執行,其標注的方法可以傳入一個TestInfo類型的參數,為當前測試信息的對象
  • @BeforeAll:在所有測試方法執行前只執行一次
  • @AfterAll:在所有測試方法執行后只執行一次

另外,@BeforeAll和@AfterAll標注的方法需要為靜態,在kotlin中需要放在companion object的代碼塊下,并用@JvmStatic注解標注


以下代碼展示了這些注解的用法:

package com.example.c0101import com.example.c0101.service.TestService
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInfo
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest@SpringBootTest
class C0101ApplicationTests {@BeforeEachfun beforeEach(info: TestInfo){println("即將進入測試方法:${info.testMethod.get()}")}@AfterEachfun afterEach(info: TestInfo){println("已經離開測試方法:${info.testMethod.get()}")}companion object {@JvmStatic@BeforeAllfun beforeAll(){println("即將進入測試")}@JvmStatic@AfterAllfun afterAll(){println("測試已完成")}}@Testfun test() {println("Hello World")}}

控制臺輸出:

...
即將進入測試
...
即將進入測試方法:public void com.example.c0101.C0101ApplicationTests.test()
Hello World
已經離開測試方法:public void com.example.c0101.C0101ApplicationTests.test()
測試已完成
...

設置測試用例

要想設置測試用例,需要使用@ParameterizedTest注解,該注解可以傳入name參數,可以為測試方法起別名。另外,可以用@ValueSource注解設置參數源:

@ParameterizedTest
@ValueSource(ints = [1, 2, 3, 4, 5])
fun test(num: Int) {println("$num")
}

注意,被@ParameterizedTest注解標注的測試方法就不需要用@Test注解標注了

JUnit會將所有的測試用例都測試一遍,因此這個測試方法會被執行5次:

...
1
2
3
4
5
...

我們也可以用@MethodSource注解設置測試用例,它將會把一個靜態方法的返回值作為測試用例:

companion object{@JvmStaticfun getInt(): Stream<Int>{return Stream.of(1, 2, 3, 4, 5)}
}@ParameterizedTest
@MethodSource("getInt")
fun test(num: Int) {println("$num")
}

注意:這里面的Stream是java.util.stream下的Stream類

使用這種方法,我們就可以傳入多個參數了:

companion object{@JvmStaticfun getProducts(): Stream<Arguments>{return Stream.of(Arguments.of("鼠標", 49.9),Arguments.of("鍵盤", 59.9))}
}@ParameterizedTest
@MethodSource("getProducts")
fun test(name: String, price: Double) {println("$name 賣 $price 元")
}

輸出:

...
鼠標 賣 49.9 元
鍵盤 賣 59.9 元
...

斷言

測試人員可以斷言一件事是真的,如果這件事不是真的,則測試失敗

JUnit提供了Assertions類,用于進行斷言:

@Test
fun test() {Assertions.assertTrue(1 > 2)
}

這段代碼斷言了1>2是真的,如果不是真的(當然不是真的),則測試失敗:

idea提示測試失敗
標題

斷言的應用

還記得之前的測試服務的代碼嗎,這個服務在傳入用戶名為admin且密碼為123456后應該返回true,如果返回的不是true,說明這個服務寫錯了;同理,如果傳入的用戶名不是admin或密碼不是123456,則應該返回false,如果返回的不是false,同樣說明這個服務寫錯了。我們可以用斷言來測試這個功能:

@Autowired
lateinit var testService: TestService@Test
fun test() {Assertions.assertTrue(testService.check("admin", "123456"))Assertions.assertTrue(!testService.check("aaa", "123"))
}

可以看到,測試通過,說明check沒有寫錯

模擬Servlet對象

如果要測試controller等需要使用Servlet對象(例如HttpServletRequest)的方法,就需要模擬Servlet對象,我們可以在測試類自動注入以下對象模擬:

@Autowired
lateinit var mockHttpServletRequest: MockHttpServletRequest
@Autowired
lateinit var mockHttpServletResponse: MockHttpServletResponse
@Autowired
lateinit var mockHttpSession: MockHttpSession

這些代碼在idea里可能會報錯,不過沒有關系

另外,在測試contoller時,同樣需要@Autowired:

@Autowired
lateinit var controller: TestController

我們來舉個模擬Servlet的例子:

先創建一個controller:

package com.example.c0101.controllerimport jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import jakarta.servlet.http.HttpSession
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController@RestController
class TestController {@RequestMappingfun index(request: HttpServletRequest, response: HttpServletResponse, session: HttpSession): String{response.status = 404return "Hello World"}}

當訪問主頁時,會設置狀態碼為404,并返回Hello World

接下來編寫測試類:

package com.example.c0101import com.example.c0101.controller.TestController
import com.example.c0101.service.TestService
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.mock.web.MockHttpServletRequest
import org.springframework.mock.web.MockHttpServletResponse
import org.springframework.mock.web.MockHttpSession@SpringBootTest
class C0101ApplicationTests {@Autowiredlateinit var controller: TestController@Autowiredlateinit var mockHttpServletRequest: MockHttpServletRequest@Autowiredlateinit var mockHttpServletResponse: MockHttpServletResponse@Autowiredlateinit var mockHttpSession: MockHttpSession@Testfun test() {val res = controller.index(mockHttpServletRequest, mockHttpServletResponse, mockHttpSession)Assertions.assertTrue(mockHttpServletResponse.status == 404)println(res)}}

測試類中,我們斷言了狀態碼一定是404,并輸出了返回結果

控制臺輸出如下:

...
Hello World
...

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/717755.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/717755.shtml
英文地址,請注明出處:http://en.pswp.cn/news/717755.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基礎二分學習筆記

模板 : 個人傾向第一種 ; 整數二分 : 最大化查找 : 可行區域在左側 : 查找最后一個<q的數的下標 : int find(int q){// 查找最后一個 < q 的下標 int l 0 , r n 1 ;while(l 1 < r){int mid l r >> 1 ;if(a[mid]<q) l mid ;else r mid ;}return…

django settings.py STATICFILES_FINDERS 設置

STATICFILES_FINDERS 定義查找器后端以確保Django能夠正確地定位和提供靜態文件是很重要的. Django中的STATICFILES FINDERS設置是一個inder后端列表&#xff0c;它知道如何在不同的位置定位靜態文件。 它被Django的靜態文件處理系統用來在開發和部署過程中查找和收集靜態文件…

js json轉換成字符串

js中JSON數據轉換成字符串&#xff0c;可以使用JSON.stringify()方法。 var obj {name: "張三", age: 18, gender: "男"}; var jsonString JSON.stringify(obj); console.log(jsonString); // 輸出 {"name":"張三","age"…

土壤類型數據

國家地球系統科學數據中心

AGM CPLD (AGRV2K )的時鐘(外部時鐘和片上內部振蕩器)

AGM CPLD &#xff08;AGRV2K &#xff09;的時鐘(外部時鐘和片上內部振蕩器) 外部晶振 與 內部振蕩器&#xff1a; mcu 和 cpld 聯合編程時&#xff0c; 整顆芯片需要一顆外部晶振。 &#xff08;芯片有內部振蕩器&#xff0c; 但誤差較大&#xff0c; 校準后 5%以內誤差&…

216. 組合總和 III(力扣LeetCode)

文章目錄 216. 組合總和 III回溯算法 216. 組合總和 III 找出所有相加之和為 n 的 k 個數的組合&#xff0c;且滿足下列條件&#xff1a; 只使用數字1到9每個數字 最多使用一次 返回 所有可能的有效組合的列表 。該列表不能包含相同的組合兩次&#xff0c;組合可以以任何順序…

Electron通過預加載腳本從渲染器訪問Node.js

問題&#xff1a;如何實現輸出Electron的版本號和它的依賴項到你的web頁面上&#xff1f; 答案&#xff1a;在主進程通過Node的全局 process 對象訪問這個信息是微不足道的。 然而&#xff0c;你不能直接在主進程中編輯DOM&#xff0c;因為它無法訪問渲染器 文檔 上下文。 它們…

【軟考】數據庫的三級模式

目錄 一、概念1.1 說明1.2 數據庫系統體系結構圖 二、外模式三、概念模式四、內模式 一、概念 1.1 說明 1.數據的存儲結構各不相同&#xff0c;但體系結構基本上具有相同的特征&#xff0c;采用三級模式和兩級鏡像 2.數據庫系統設計員可以在視圖層、邏輯層和物理層對數據進行抽…

matplotlib散點圖

matplotlib散點圖 假設通過爬蟲你獲取到了北京2016年3, 10月份每天白天的最高氣溫(分別位于列表a, b), 那么此時如何尋找出氣溫和隨時間(天)變化的某種規律? from matplotlib import pyplot as pltx_3 range(1, 32) x_10 range(51, 82)y_3 [11,17,16,11,12,11,12,6,6,7,8…

試手一下CameraX(APP)

書接上回。 首先還是看谷歌的官方文檔&#xff1a; https://developer.android.com/media/camera/camerax?hlzh-cn https://developer.android.com/codelabs/camerax-getting-started?hlzh-cn#1 注&#xff1a;這里大部分內容也來自谷歌文檔。 官方文檔用的是Kotlin&…

常用的字符字符串的讀取方法(C / C++)

一、字符 1、讀取單個字符&#xff1a;直接讀取 //輸入a //讀取 char x; scanf("%c",&x); 2、讀取帶空格的字符 h h h 按格式書寫格式化字符串即可 char a,b,c; scanf("%c %c %c",&a,&b,&c); 3、 處理字符間的換行符 假設要讀取以…

Day14:信息打點-主機架構蜜罐識別WAF識別端口掃描協議識別服務安全

目錄 Web服務器&應用服務器差異性 WAF防火墻&安全防護&識別技術 蜜罐平臺&安全防護&識別技術 思維導圖 章節知識點 Web&#xff1a;語言/CMS/中間件/數據庫/系統/WAF等 系統&#xff1a;操作系統/端口服務/網絡環境/防火墻等 應用&#xff1a;APP對象/…

小程序圖形:echarts-weixin 入門使用

去官網下載整個項目&#xff1a; https://github.com/ecomfe/echarts-for-weixin 拷貝ec-canvs文件夾到小程序里面 index.js里面的寫法 import * as echarts from "../../components/ec-canvas/echarts" const app getApp(); function initChart(canvas, width, h…

Vscode 使用SSH遠程連接樹莓派的教程(解決卡在Downloading with wget)

配置Vscode Remote SSH 安裝OpenSSH 打開Windows開始頁面&#xff0c;直接進行搜索PowerShell&#xff0c;打開第一個Windows PowerShell&#xff0c;點擊以管理員身份運行 輸入指令 Get-WindowsCapability -Online | ? Name -like OpenSSH* 我是已經安裝好了&#xff0c;…

學會玩游戲,智能究竟從何而來?

最近在讀梅拉妮米歇爾《AI 3.0》第三部分第九章&#xff0c;談到學會玩游戲&#xff0c;智能究竟從何而來&#xff1f; 作者: [美] 梅拉妮米歇爾 出版社: 四川科學技術出版社湛廬 原作名: Artificial Intelligence: A Guide for Thinking Humans 譯者: 王飛躍 / 李玉珂 / 王曉…

基于springboot實現計算機類考研交流平臺系統項目【項目源碼+論文說明】

基于springboot實現計算機類考研交流平臺系統演示 摘要 高校的大學生考研是繼高校的高等教育更上一層的表現形式&#xff0c;教育的發展是我們社會的根本&#xff0c;那么信息技術的發展又是改變我們生活的重要因素&#xff0c;生活當中各種各樣的場景都存在著信息技術的發展。…

程序員超強大腦——更好地解決編程問題(二)

概念機器 概念機器是計算機的抽象表征&#xff0c;可以借此分析計算機執行的操作。 程序員不僅經常借助概念機器推理計算機的運行方式&#xff0c;而且往往用它來分析代碼。例如&#xff0c;雖然并不存在能夠出存儲數值的實體&#xff0c;但程序員還是會將變量描述為“保存”…

Debezium發布歷史163

原文地址&#xff1a; https://debezium.io/blog/2023/09/23/flink-spark-online-learning/ 歡迎關注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻譯&#xff0c;僅供參考&#xff0c;筆芯筆芯. Online machine learning with the data streams from the database …

SpringBlade CVE-2022-27360 export-user SQL 注入漏洞分析

漏洞描述 SpringBlade是一個基于Spring Cloud和Spring Boot的開發框架&#xff0c;旨在簡化和加速微服務架構的開發過程。它提供了一系列開箱即用的功能和組件&#xff0c;幫助開發人員快速構建高效可靠的微服務應用。該產品/api/blade-user/export-user接口存在SQL注入。 漏…

Java - List集合與Array數組的相互轉換

一、List 轉 Array 使用集合轉數組的方法&#xff0c;必須使用集合的 toArray(T[] array)&#xff0c;傳入的是類型完全一樣的數組&#xff0c;大小就是 list.size() public static void main(String[] args) throws Exception {List<String> list new ArrayList<S…