注入返回值——TIL 項(xiàng)目 JavaScript 實(shí)戰(zhàn)筆記)
文檔教程知識(shí)庫(kù)【免費(fèi)下載鏈接】til:memo: Today I Learned項(xiàng)目地址https://gitcode.com/gh_mirrors/ti/til點(diǎn)擊查看免費(fèi)下載本篇技術(shù)指南聚焦 TIL 倉(cāng)庫(kù) javascript/mock-a-function-with-return-values-using-jest 所記錄的核心技巧如何用jest.fn()創(chuàng)建 Mock 函數(shù)并通過mockReturnValue()/mockReturnValueOnce()為它注入固定或一次性返回值從而讓被測(cè)代碼在無需真實(shí)依賴的情況下穩(wěn)定運(yùn)行。讀完本文你將掌握 Mock 函數(shù)從創(chuàng)建、賦值、注入返回值到落地到組件測(cè)試與定時(shí)器測(cè)試的完整鏈路并了解它與mockImplementation、mockResolvedValue等姊妹 API 的關(guān)系。一、起步用 jest.fn() 創(chuàng)建 Mock 函數(shù)Jest 為處理 Mock 函數(shù)提供了一整套工具集合Mock Function API其中最基礎(chǔ)的入口就是jest.fn()。調(diào)用它即可得到一個(gè)全新的 Mock 函數(shù)該函數(shù)本身不執(zhí)行任何業(yè)務(wù)邏輯而是由測(cè)試代碼按需配置其行為。jest.fn() // 賦值給一個(gè)變量 const fakeFunc jest.fn(); // 作為 prop 傳給組件 SpecialInput handleChange{jest.fn()} /從上面的三行代碼可以看到j(luò)est.fn()的三種典型用法直接調(diào)用生成一個(gè)未綁定的 Mock 函數(shù)實(shí)例賦值給變量將 Mock 函數(shù)保存為fakeFunc后續(xù)可以通過該變量統(tǒng)一配置返回值、調(diào)用次數(shù)等行為作為 prop 傳入組件在渲染組件時(shí)傳入一個(gè) Mock 函數(shù)如上面的handleChange用于占位并觀測(cè)組件是否正確調(diào)用了該回調(diào)。這一點(diǎn)在 TIL 倉(cāng)庫(kù)的 react/mock-a-function-that-a-component-imports 中有直接的印證——當(dāng)組件依賴一個(gè)導(dǎo)入的函數(shù)isAuthenticated()時(shí)測(cè)試中正是用jest.fn().mockReturnValue(true)來替換真實(shí)實(shí)現(xiàn)而在 xstate/custom-jest-matcher-for-xstate-machine-states 中XState 機(jī)器的action: jest.fn()同樣以 Mock 函數(shù)來觀測(cè)動(dòng)作是否被觸發(fā)。二、mockReturnValue()讓 Mock 函數(shù)始終返回指定值創(chuàng)建出 Mock 函數(shù)之后下一步就是為它配置返回值。最常用的方法是mockReturnValue(value)const fakeFunc jest.fn(); fakeFunc.mockReturnValue(hello); fakeFunc(); // hellomockReturnValue()的核心語義是無論函數(shù)被調(diào)用多少次只要沒有更優(yōu)先的一次性配置它都會(huì)返回同一個(gè)值。在上述示例中fakeFunc每次被調(diào)用都會(huì)得到字符串hello測(cè)試代碼無需關(guān)心函數(shù)內(nèi)部邏輯只需確認(rèn)當(dāng)這個(gè)函數(shù)被調(diào)用時(shí)它會(huì)返回什么這正是單元測(cè)試隔離外部依賴的關(guān)鍵手法。這種恒定返回值在真實(shí)測(cè)試場(chǎng)景中極其常用。TIL 倉(cāng)庫(kù)的 react/mock-a-function-that-a-component-imports 給出了一個(gè)完整的落地案例// MyComponent.test.js // ... various testing imports import * as authModules from ./authentication; it(renders the component, () { authModules.isAuthenticated jest.fn().mockReturnValue(true); const wrapper shallow(MyComponent /); expect(toJson(wrapper)).toMatchSnapshot(); });這里通過import * as authModules拿到與MyComponent相同的模塊引用把isAuthenticated替換為jest.fn().mockReturnValue(true)的 Mock 版本。于是渲染MyComponent時(shí)組件內(nèi)部調(diào)用到的isAuthenticated()會(huì)返回true從而走入已認(rèn)證分支測(cè)試無需真實(shí)登錄態(tài)。反向場(chǎng)景只需要把返回值換成falseauthModules.isAuthenticated jest.fn().mockReturnValue(false);一句話總結(jié)mockReturnValue()的價(jià)值在于凡調(diào)用必返回讓依賴方在固定前提下被穩(wěn)定驅(qū)動(dòng)。三、mockReturnValueOnce()讓返回值只生效一次與mockReturnValue()相對(duì)mockReturnValueOnce(value)只讓指定返回值生效一次隨后的調(diào)用不再返回該值const fakeFunc jest.fn(); fakeFunc.mockReturnValueOnce(hello); fakeFunc(); // hello fakeFunc(); // nullmockReturnValueOnce()的語義是第一次調(diào)用時(shí)返回配置值之后回落到 Mock 函數(shù)的默認(rèn)行為。這里有一個(gè)容易被忽略的細(xì)節(jié)需要澄清在 Jest 中未配置任何返回值/實(shí)現(xiàn)的 Mock 函數(shù)其默認(rèn)調(diào)用結(jié)果實(shí)際上是undefined而不是null原始筆記以null概括此后不再返回任何配置值這一結(jié)果讀者理解其意圖即可在編寫斷言時(shí)請(qǐng)以實(shí)際默認(rèn)值undefined為準(zhǔn)。該 API 最典型的用途是模擬前幾次調(diào)用返回特殊值的場(chǎng)景例如模擬輪詢接口第一次返回處理中后續(xù)返回已完成模擬數(shù)據(jù)庫(kù)查詢某次查詢命中緩存返回 A其余返回 B模擬需要多次調(diào)用才穩(wěn)定的第三方 SDK。四、組合運(yùn)用默認(rèn)返回值 一次性覆蓋mockReturnValue()與mockReturnValueOnce()并不互斥二者組合可以表達(dá)大部分調(diào)用返回默認(rèn)值僅某幾次調(diào)用返回特殊值的行為const fakeFunc jest.fn(); fakeFunc .mockReturnValue(default) .mockReturnValueOnce(first) .mockReturnValueOnce(second); fakeFunc(); // first fakeFunc(); // second fakeFunc(); // default fakeFunc(); // default組合時(shí)的優(yōu)先級(jí)規(guī)則是一次性配置Once系列總是先于永久配置mockReturnValue系列被消費(fèi)。所有Once值按注冊(cè)順序依次消耗完畢后函數(shù)才回落到mockReturnValue設(shè)置的恒定值。這一規(guī)則讓先特殊、后通用的測(cè)試編排變得非常直觀。五、倉(cāng)庫(kù)實(shí)例Mock 函數(shù)在定時(shí)器與日志測(cè)試中的落地除了注入返回值jest.fn()的調(diào)用記錄能力也是斷言的核心依據(jù)。TIL 倉(cāng)庫(kù)的 javascript/test-timing-based-code-with-jest-fake-timers 展示了jest.fn()與假定時(shí)器配合、用toHaveBeenCalled()驗(yàn)證調(diào)用是否發(fā)生的完整流程jest.useFakeTimers(); describe(doSomethingAfter200ms, () { test(does something after 200ms (pass), () { const doSomething jest.fn(); doSomethingAfter200ms(doSomething); jest.advanceTimersByTime(201); expect(doSomething).toHaveBeenCalled(); }); });這里doSomething無需關(guān)心返回值——Mock 函數(shù)同時(shí)具備可配置行為與可觀測(cè)調(diào)用歷史兩種能力。類似的模式還出現(xiàn)在 javascript/turn-off-console-error-messages-in-a-test 中通過console.error jest.fn()屏蔽測(cè)試期的噪音輸出。結(jié)合這兩個(gè)倉(cāng)庫(kù)實(shí)例可以得出jest.fn()是注入返回值 記錄調(diào)用歷史的統(tǒng)一入口而mockReturnValue只是它眾多行為配置中的一支。六、延伸mockReturnValue 的姊妹 APImockReturnValue與mockReturnValueOnce屬于 Jest Mock Function API 家族理解它們后可以順帶掌握同族的其他常用成員它們共享永久/一次性與普通值/異步值兩對(duì)維度的組合邏輯API語義mockReturnValue(value)每次調(diào)用都返回該值本文主題mockReturnValueOnce(value)僅下一次調(diào)用返回該值本文主題mockImplementation(fn)用自定義函數(shù)完全接管 Mock 函數(shù)的行為mockImplementationOnce(fn)僅下一次調(diào)用使用自定義實(shí)現(xiàn)mockResolvedValue(value)等價(jià)于mockImplementation(() Promise.resolve(value))用于返回已兌現(xiàn)的 PromisemockResolvedValueOnce(value)僅下一次調(diào)用返回已兌現(xiàn)的 PromisemockRejectedValue(value)等價(jià)于mockImplementation(() Promise.reject(value))用于模擬異步失敗選擇建議當(dāng)被測(cè)代碼只需要知道返回值時(shí)優(yōu)先用mockReturnValue系列更簡(jiǎn)潔當(dāng)需要模擬真實(shí)邏輯或異步行為時(shí)再考慮mockImplementation與mockResolvedValue系列。配合toHaveBeenCalled()、toHaveReturnedWith(value)等斷言即可對(duì)返回值是否被正確注入、調(diào)用是否發(fā)生做完整的雙向驗(yàn)證。小結(jié)圍繞 TIL 倉(cāng)庫(kù) javascript/mock-a-function-with-return-values-using-jest 這篇筆記本文完整覆蓋了jest.fn()創(chuàng)建 Mock 函數(shù)的三種方式、mockReturnValue()的恒定返回值語義、mockReturnValueOnce()的一次性語義及回落后返回undefined的細(xì)節(jié)并補(bǔ)充了二者組合時(shí)的優(yōu)先級(jí)規(guī)則。結(jié)合倉(cāng)庫(kù)中 react/mock-a-function-that-a-component-imports、javascript/test-timing-based-code-with-jest-fake-timers 與 javascript/turn-off-console-error-messages-in-a-test 的實(shí)戰(zhàn)樣例可以看到注入返回值只是 Mock 函數(shù)能力的入口配合調(diào)用歷史斷言與一次性覆蓋足以支撐絕大多數(shù)前端與 Node 側(cè)單元測(cè)試場(chǎng)景。贊分享文檔教程知識(shí)庫(kù)【免費(fèi)下載鏈接】til:memo: Today I Learned項(xiàng)目地址https://gitcode.com/gh_mirrors/ti/til點(diǎn)擊查看免費(fèi)下載相關(guān)推薦rust-bert 在生產(chǎn)環(huán)境中的應(yīng)用案例從初創(chuàng)公司到大型企業(yè)的成功實(shí)踐rust bert 在生產(chǎn)環(huán)境中的應(yīng)用案例從初創(chuàng)公司到大型企業(yè)的成功實(shí)踐 rust bert 是一個(gè)基于 Rust 語言的原生自然語言處理NLP框架它提人工智能深度學(xué)習(xí)大模型30 Seconds of Code 實(shí)戰(zhàn)用 debouncePromise 為 JavaScript 防抖函數(shù)返回 Promise30 Seconds of Code 實(shí)戰(zhàn)用 debouncePromise 為 JavaScript 防抖函數(shù)返回 Promise 本文以 30 secon教程文檔深入解析 freeCodeCamp Basic JavaScript 課程用 return 語句返回函數(shù)值深入解析 freeCodeCamp Basic JavaScript 課程用 return 語句返回函數(shù)值 本文圍繞 freeCodeCamp 開源課程 Ba前端后端教育上一篇Austin項(xiàng)目實(shí)戰(zhàn)指南下一篇Anima開源項(xiàng)目使用教程創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考