Mock 單元測試

作者:小凱
沉淀、分享、成長,讓自己和他人都能有所收獲!

本文的宗旨在于通過簡單干凈實踐的方式教會讀者,如何使用 Mock (opens new window)進行工程的單元測試,以便于驗證系統中的獨立模塊功能的健壯性。

從整個工程所處不同階段的測試手段包括;單元測試、集成測試、系統測試、驗收測試、性能測試、安全測試、回歸測試,以及兼容、可靠、可用性測試。

而單元測試的重點在于,對工程開發中的代碼,進行流程中的單元化測試。如一整個下單流程中,需要調用各項外部的接口(風控、賬戶、營銷、試算、支付),才能完成整個下單流程。但在本地開發過程中,不太能將所有的外部接口都調試為開發環境可用狀態,所有這個時候要做單元化測試,對于一些不能隨時提供服務的接口進行 Mock (opens new window)處理。

一、案例背景
因為 Mock 單元測試的重點,主要體現在;功能流程較長、調用外部接口穩定性較差、測試過程中希望可以不啟動 SpringBoot 應用就能對單個功能模塊進行測試驗證。

所以本章節帶著這樣一個案例背景的情況,這里通過 《HTTP 框架使用和場景實戰 - 結合ChatGLM自動回帖!》 (opens new window)做一個小重構。來對 Mock 框架進行驗證使用。
在這里插入圖片描述

首先,這里使用 DDD 工程模型結構,搭建出測試工程。—— DDD 是一種軟件設計方法,而軟件的設計方法涵蓋了;范式、模型、框架、方法論。所以通常下 MVC 與 DDD 的對比先從模型、框架在到思想設計和方法論。
之后,我們在這樣的一個模型結構下,實現出自動回帖的領域功能。而這個模型的實現恰好需要調用外部的接口和 ChatGLM SDK,這與我們要做的 Mock 測試正好符合,因為在大部分開發場景下,遠程的 HTTP 調用可能不不會一直可用,所以可以用 Mock 方式進行模擬。
二、功能實現
1. 工程結構
在這里插入圖片描述

  • 在 domain 中實現一個zsxq的自動回帖領域,而它所需的要調用的接口則由基礎設施層提供。
  • 另外在 app 中還有 ChatGLM SDK 的配置啟動,也會被注入到 AiReply 實現類中。

2. Ai模塊啟動

# ChatGLM SDK Config
chatglm:sdk:config:# 狀態;true = 開啟、false 關閉enabled: false# 官網地址api-host: https://open.bigmodel.cn/# 官網申請 https://open.bigmodel.cn/usercenter/apikeysapi-secret-key: d570f7c5d289cdac2abdfdc562e39f3f.trqz1dH8ZK6ED7Pg
@Bean
@ConditionalOnProperty(value = "chatglm.sdk.config.enabled", havingValue = "true", matchIfMissing = false)
public OpenAiSession openAiSession(ChatGLMSDKConfigProperties properties) {// 1. 配置文件cn.bugstack.chatglm.session.Configuration configuration = new cn.bugstack.chatglm.session.Configuration();configuration.setApiHost(properties.getApiHost());configuration.setApiSecretKey(properties.getApiSecretKey());// 2. 會話工廠OpenAiSessionFactory factory = new DefaultOpenAiSessionFactory(configuration);// 3. 開啟會話return factory.openSession();
}
  • 所有的這些配置類的服務,都可以放到 app下的 config 模塊中。
  • ChatGLM 可以直接在官網申請,默認會贈送18元的額度,對于它所提供的模型,還是非常夠測試使用的。

3. 基礎設置 - 接口調用
3.1 接口 - 防腐對接
源碼:cn.bugstack.xfg.dev.tech.infrastructure.gateway.api.IZSXQApi

public interface IZSXQApi {/*** 查詢知識星球帖子內容** @return 帖子數據* @throws IOException 異常*/ResponseDTO topics() throws IOException;/*** 回復帖子** @param topicId 帖子ID* @param content 回復內容*/void comment(long topicId, String content);}
  • 在基礎設置層中定義 gateway 網關接口調用,對于外部的接口使用,中間要做一層防腐,不要直接把外部的接口暴露出去使用。

3.2 使用 - 依賴倒置
源碼:cn.bugstack.xfg.dev.tech.infrastructure.gateway.adapter.ZSXQAdapter

public class ZSXQAdapter implements IZSXQAdapter {@Resourceprivate IZSXQApi zsxqApi;@Overridepublic List<TopicsItemVO> queryTopics() {try {ResponseDTO responseDTO = zsxqApi.topics();RespData respData = responseDTO.getRespData();List<TopicsItem> topics = respData.getTopics();List<TopicsItemVO> topicsItemVOList = new ArrayList<>();for (TopicsItem topicsItem : topics) {TopicsItemVO topicsItemVO = TopicsItemVO.builder().topicId(topicsItem.getTopicId()).talk(topicsItem.getTalk().getText()).showCommentsItems(topicsItem.getShowComments() != null ? topicsItem.getShowComments().stream().map(showCommentsItem -> {TopicsItemVO.ShowCommentsItem item = new TopicsItemVO.ShowCommentsItem();item.setUserId(showCommentsItem.getOwner().getUserId());return item;}).collect(Collectors.toList()) : new ArrayList<>()).build();topicsItemVOList.add(topicsItemVO);}return topicsItemVOList;} catch (IOException e) {throw new RuntimeException(e);}}@Overridepublic boolean comment(long topicId, String content) {zsxqApi.comment(topicId, content);return true;}}
  • 注意,TopicsItemVO 對象來自于 domain 下領域中模型下的 VO 對象。因為是依賴倒置的,所以 infrastructure 引用的是 domain 并對其接口做實現處理。
  • 并且,TopicsItemVO 只是需要獲取自己需要的對象,還可以做簡單的封裝處理。這樣可以銜接外部接口和內部邏輯中間的橋梁,不做強關聯。

4. 任務調度
源碼:cn.bugstack.xfg.dev.tech.job.ReplyJob

public class ReplyJob {@Resourceprivate IAiReply aiReply;@Scheduled(cron = "0/10 * * * * ?")public void exec() throws Exception {log.info("自動回帖任務開始執行...");aiReply.doAiReply();}}
  • 現在在 trigger 觸發器層中的 job 下,就可以調用我們已經實現好的 AiReply 自動回帖功能了。
  • 此外,注意 Application 中 @EnableScheduling 注解是開啟的,否則任務不能執行。

三、系統測試
1. 集成測試

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApiTest {@Resourceprivate IAiReply aiReply;@Testpublic void test_IAiReply() {aiReply.doAiReply();}}
  • 通常情況下這種測試是最多的,寫多少功能,就直接測試調用。如功能中所用到的;HTTP接口、RPC接口、數據庫、Redis等資源,都會需要使用到。有時候也因為這樣,所以不好測試。那么單元測試就出現了。

2. 單元測試

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class MockTest {@Resourceprivate IAiReply aiReply;@MockBeanprivate IZSXQAdapter izsxqAdapter;@Testpublic void test_doAiReply() throws InterruptedException, JsonProcessingException {Mockito.when(izsxqAdapter.queryTopics()).thenReturn(new ArrayList<TopicsItemVO>() {{TopicsItemVO topicsItemVO = new TopicsItemVO();topicsItemVO.setTopicId(10001L);topicsItemVO.setTalk("<e type=\"mention\" uid=\"241858242255511\" title=\"%40%E5%B0%8F%E5%82%85%E5%93%A5\" /> 提問 java 冒泡排序");add(topicsItemVO);}});Mockito.when(izsxqAdapter.comment(Mockito.anyLong(), Mockito.anyString())).thenReturn(true);aiReply.doAiReply();// 等待;ChatGLM 異步回復new CountDownLatch(1).await();}}

在這里插入圖片描述

  • 在基于使用 SpringBoot 的啟動,以及一部分功能需要走真實調用的情況下,另外一部分功能的接口可能沒法調用時。可以使用這樣的一種 MockBean 的方式進行處理,并對整條鏈路上調用到的接口方法進行 Mock 處理。`Mockito.when(調用到的接口).thenReturn(返回的結果);
  • 那么現在在測試方法中,做了2個Mock操作,把查詢帖子和回復帖子,都給處理掉。也就是有了 Mock 以后,程序調用到這里,就直接走 Mock 里設置的結果信息了。

3. 功能測試

@Slf4j
@RunWith(MockitoJUnitRunner.class)
public class ZSXQAdapterTest {@Mockprivate IZSXQApi mockZsxqApi;@InjectMocksprivate ZSXQAdapter zsxqAdapterUnderTest;@Testpublic void testQueryTopics() throws Exception {// Setupfinal List<TopicsItemVO> expectedResult = Arrays.asList(TopicsItemVO.builder().topicId(0L).talk("talk").showCommentsItems(Arrays.asList(TopicsItemVO.ShowCommentsItem.builder().userId(0L).build())).build());// Configure IZSXQApi.topics(...).final ResponseDTO responseDTO = new ResponseDTO();final RespData respData = new RespData();final TopicsItem topicsItem = new TopicsItem();final ShowCommentsItem showCommentsItem = new ShowCommentsItem();final Owner owner = new Owner();owner.setUserId(0L);showCommentsItem.setOwner(owner);topicsItem.setShowComments(Arrays.asList(showCommentsItem));final Talk talk = new Talk();talk.setText("talk");topicsItem.setTalk(talk);topicsItem.setTopicId(0L);respData.setTopics(Arrays.asList(topicsItem));responseDTO.setRespData(respData);when(mockZsxqApi.topics()).thenReturn(responseDTO);// Run the testfinal List<TopicsItemVO> result = zsxqAdapterUnderTest.queryTopics();// Verify the resultsassertEquals(expectedResult, result);log.info("測試結果:{}", JSON.toJSONString(result));}}

在這里插入圖片描述

  • 除了前面兩種測試,我們在開發功能的時候,還有場景測試;不啟動 SpringBoot 但希望對實現的功能進行測試。
  • 那么這里所體現的就是這樣的測試,主要使用;@RunWith(MockitoJUnitRunner.class)、@Mock、@InjectMocks 相當于模擬了一個啟動的過程,只不過都是 Mock 的信息。但你可以根據這些信息來調試你的接口。
  • 提示:你可以安裝 IDEA Plugin Squaretest 它能自動的幫你生成Mock單元測試。這個插件是收費的,但還好不貴。

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

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

相關文章

MySQL 深度性能優化配置實戰指南

?? 一、硬件與系統層優化:夯實性能基石 ??硬件選型策略?? ??CPU??:讀密集型場景選擇多核CPU(如32核);寫密集型場景選擇高主頻CPU(如3.5GHz+)。 ??內存??:建議≥64GB,??緩沖池命中率≥99%?? 是性能關鍵指標。 ??存儲??:??必用NVMe SSD??,I…

Visual Studio Code(VSCode)中設置中文界面

在VS Code中設置中文界面主要有兩種方法&#xff1a;通過擴展市場安裝中文語言包或通過命令面板直接切換語言。?方法一&#xff1a;通過擴展市場安裝中文語言包?打開VS Code&#xff0c;點擊左側活動欄的"擴展"圖標&#xff08;或按CtrlShiftX&#xff09;。在搜索…

叉車機器人如何實現托盤精準定位?這項核心技術的原理和應用是什么?

隨著智慧物流和智能制造的加速發展&#xff0c;智能化轉型成為提升效率、降低成本的關鍵路徑&#xff0c;叉車機器人&#xff08;AGV/AMR叉車&#xff09;在倉儲、制造、零售等行業中的應用日益廣泛。 其中&#xff0c;托盤定位技術是實現其高效、穩定作業的核心環節之一&…

NO.6數據結構樹|二叉樹|滿二叉樹|完全二叉樹|順序存儲|鏈式存儲|先序|中序|后序|層序遍歷

樹與二叉樹的基本知識 樹的術語結點&#xff1a; 樹中的每個元素都稱為結點&#xff0c; 例如上圖中的 A,B,C…根結點&#xff1a; 位于樹頂部的結點&#xff0c; 它沒有父結點,比如 A 結點。父結點&#xff1a; 若一個結點有子結點&#xff0c; 那么這個結點就稱為其子結點的父…

數據集下載網站

名稱簡介鏈接Kaggle世界上最大的數據科學競賽平臺之一&#xff0c;有大量結構化、圖像、文本等數據集可直接下載?支持一鍵下載、APIPapers with Code可按任務&#xff08;如圖像分類、文本生成等&#xff09;查找模型與數據集&#xff0c;標注 SOTA?與論文強關聯Hugging Face…

Tomcat 生產 40 條軍規:容量規劃、調優、故障演練與安全加固

&#xff08;一&#xff09;容量規劃 6 條 軍規 1&#xff1a;線程池公式 maxThreads ((并發峰值 平均 RT) / 1000) 冗余 20 %&#xff1b; 踩坑&#xff1a;壓測 2000 QPS、RT 200 ms&#xff0c;理論 maxThreads500&#xff0c;線上卻設 150 導致排隊。軍規 2&#xff1a;…

深入解析 Amazon Q:AWS 推出的企業級生成式 AI 助手

在人工智能助手競爭激烈的當下&#xff0c;AWS 重磅推出的 Amazon Q 憑借其強大的企業級整合能力&#xff0c;正成為開發者提升生產力的新利器。隨著生成式 AI 技術席卷全球&#xff0c;各大云廠商紛紛布局智能助手領域。在 2023 年 re:Invent 大會上&#xff0c;AWS 正式推出了…

物流自動化WMS和WCS技術文檔

導語大家好&#xff0c;我是社長&#xff0c;老K。專注分享智能制造和智能倉儲物流等內容。歡迎大家使用我們的倉儲物流技術AI智能體。新書《智能物流系統構成與技術實踐》新書《智能倉儲項目出海-英語手冊&#xff0c;必備&#xff01;》完整版文件和更多學習資料&#xff0c;…

Web3.0 實戰項目、簡歷打造、精準投遞+面試準備

目錄 一、獲取真實企業級 Web3.0 項目的 5 種方式 1. 參與開源項目&#xff08;推薦指數&#xff1a;?????&#xff09; 2. 參與黑客松&#xff08;Hackathon&#xff09; 3. 遠程實習 & DAO 協作項目&#xff08;兼職也可&#xff09; 4. Web3 Startup 實戰項目合…

pymongo庫:簡易方式存取數據

文檔 基礎使用 前提&#xff1a;開發機器已安裝mongo配置環境&#xff0c;已啟動服務。 macOS啟動服務&#xff1a;brew services start mongodb-community8.0 macOS停止服務&#xff1a;brew services stop mongodb-community8.0安裝&#xff1a;python3 -m pip install pym…

Java 線程池與多線程并發編程實戰全解析:從異步任務調度到設計模式落地,200 + 核心技巧、避坑指南與業務場景結合

多線程編程在現代軟件開發中扮演著至關重要的角色&#xff0c;它能夠顯著提升應用程序的性能和響應能力。通過合理利用異步線程、多線程以及線程池等技術&#xff0c;我們可以更高效地處理復雜任務&#xff0c;優化系統資源的使用。同時&#xff0c;在實際應用中&#xff0c;我…

gitee 分支切換

ssh-keygen -t rsa -C "pengchengzhangcplaser.com.cn" ssh -T gitgitee.comgit remote add origin 倉庫地址git config --global user.email "youexample.com"git config --global user.name "Your Name"# 1. 更新遠程信息 git fetch origin# …

Vue3生命周期函數

在 Vue 3 中&#xff0c;生命周期鉤子函數是指組件從創建到銷毀的整個過程中&#xff0c;Vue 自動調用的一些特定函數。它們讓你能夠在組件的不同階段執行一些自定義操作。Vue 3 提供了組合式 API 和選項式 API 兩種方式來定義生命周期鉤子。1. onBeforeMount (組合式 API)作用…

基于SEP3203微處理器的嵌入式最小硬件系統設計

目錄 1 引言 2 嵌入式最小硬件系統 3 SEP3202簡述 4 最小系統硬件的選擇和單元電路的設計 4.1 電源電路 4.2 晶振電路 4.3 復位及喚醒電路 4.5 存儲器 4.5.1 FLASH存儲 4.5.2 SDRAM 4.6 串行接口電路設計 4.7 JTAG模塊 4.8 擴展功能&#xff08;LED&#xff09; …

【開源軟件推薦】 SmartSub,一個可以快速識別視頻/音頻字幕的工具

背景介紹 我就說Github上面能找到好東西吧 事情是這樣的 我最近在用PC端的剪映剪輯視頻 需要用到它的語音轉字幕功能 轉完之后&#xff0c;導出的時候 發現 赫然有一項字幕識別的會員權益 我尋思看看什么價格 不貴的話就充了 好家伙&#xff0c;這不看不知道&#xff…

自動駕駛仿真領域常見開源工具

自動駕駛仿真領域常見開源工具1、目錄1.1 自動駕駛仿真領域常見開源2、地圖&場景2.1、場景播放器-Esmini4、被測對象-智駕軟件4.1、Autoware4.4、端到端模型-VAD4.5、端到端模型-UniAD4.6、端到端模型-ThinkTwice4.7、端到端模型-TCP5、評價方法5.1、Leaderboard5.2、Bench…

GPU算力租用平臺推薦,價格便宜且有羊毛薅,最低只要0.49/小時!

1.趨動云&#xff0c;這是我近期一直在用的&#xff0c;使用體驗還不錯&#xff0c;推薦給大家 網址&#xff1a;https://platform.virtaicloud.com/gemini_web/auth/register?inviteCode5f74065eac6d8867eac5c82194e2683a 是否選擇一個算力平臺我認為有幾點需要考慮&#xff…

python學智能算法(二十五)|SVM-拉格朗日乘數法理解

引言 前序學習進程中&#xff0c;已經對最佳超平面的求解有了一定認識。 剛好在此梳理一下: 函數距離 首先有函數距離F&#xff0c;也可以稱為函數間隔F&#xff1a; Fmin?i1...myi(w?xib)F \min_{i1...m}y_{i}(w \cdot x_{i}b)Fi1...mmin?yi?(w?xi?b) 幾何距離 然后…

vscode 源碼編譯

windows 環境 下載安裝 build tools Visual Studio Build Tools 勾選 C 因為安裝詳細信息里是 v143&#xff0c;所以單個組件里也要追加兩個 143 的勾選 點擊安裝&#xff0c;安裝好重啟下電腦 Electron 安裝失敗&#xff1a;connect ETIMEDOUT 20.205.243.166:443 為防Ele…

讀取和寫入json,xml文件

一、JSON文件操作? 1. 核心類?? ??QJsonDocument??&#xff1a;表示整個JSON文檔&#xff0c;提供解析&#xff08;fromJson()&#xff09;和序列化&#xff08;toJson()&#xff09;功能。 ??QJsonObject??&#xff1a;存儲鍵值對集合&#xff0c;支持嵌套對象和數…