国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 web前端 js教程 測試 ReactJS 上下文 - 測試替身指南

測試 ReactJS 上下文 - 測試替身指南

Dec 05, 2024 am 02:03 AM

在這篇文章中,我將逐步介紹使用測試庫測試依賴于上下文的 React 組件的思維過程。我的目標是探索一種不同的方法來測試這些組件,檢查使用模擬與不模擬上下文的測試的優(yōu)缺點。我們將研究每種方法如何影響測試的可靠性,并且我將分享關于何時以及為什么一種方法在實際應用中可能比另一種方法更有益的見解。

你應該知道什么

  • reactjs 是用來做什么的(可能你已經(jīng)寫過一些應用了)
  • 什么是 vitest

什么是反應上下文

ReactJS 上下文的出現(xiàn)是為了解決 ReactJS 組件結(jié)構(gòu)中的一個常見問題:道具鉆探。當我們有一系列組件需要訪問同一組數(shù)據(jù)時,就會發(fā)生道具鉆探。上下文機制允許組件共享同一組數(shù)據(jù),只要上下文本身是第一個后代。

在reactjs文檔中,使用了保存主題的上下文,因為其他組件可能需要此信息,文檔使用上下文來處理該信息,而不是通過道具傳遞值。另一個示例是使用上下文來保存應用程序的布局,在 json-tool 示例中,App.tsx 使用可用于所有應用程序的 DefaultLayout 上下文來包裝應用程序。

本示例的應用程序

下面的示例將使用主題應用程序。它是一個允許用戶在淺色/深色主題之間切換的應用程序。該應用程序也在reactjs官方文檔中使用。該應用程序由一個簡單的開關組成,可以在淺色主題模式和深色主題模式之間切換。該應用程序非常簡單,我們可以將所有內(nèi)容繪制在一個文件中:

import { createContext, useContext, useState } from 'react'
const ThemeContext = createContext('light')

function Page() {
  const theme = useContext(ThemeContext)
  return (
    <div>
      <p>current theme: {theme}</p>
    </div>
  )
}

function App() {
  const [theme, setTheme] = useState('light')
  return (
    <ThemeContext.Provider value={theme}>
      <button
        className={theme}
        onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
      >
        Toggle
      </button>
      <Page />
    </ThemeContext.Provider>
  )
}

export default App

在這個應用程序中,我們有兩個主要組件:App 和 Page。 App 組件作為主要組件,包含當前主題的狀態(tài),可以是“亮”或“暗”。它還包括一個可在淺色和深色模式之間切換主題的按鈕。 Page 組件是 App 的子組件,它使用主題上下文來顯示當前主題。 App 組件中的按鈕是一個簡單的切換按鈕,單擊時會切換主題并相應地更新上下文值。

Testing ReactJS Context - A Guide with test-doubles

在下一節(jié)中,我們將討論對組件進行切片以進行測試。

點火測試

通常在任何應用程序中,我們都必須專注于我們想要做什么樣的測試,以及我們想要處理哪個部分。例如,我們可以針對單個組件,而不是整個應用程序。在我們的示例中,我們將從頁面組件開始。這將需要我們使用測試替身來測試它。

Testing ReactJS Context - A Guide with test-doubles

測試替身來自應用程序結(jié)構(gòu)本身,因為它取決于上下文,要更改它,上下文中的值也需要更改。

測試雙打

為了開始使用 ReactJS 中的上下文進行測試方法,我們將開始編寫第一個測試:

import { createContext, useContext, useState } from 'react'
const ThemeContext = createContext('light')

function Page() {
  const theme = useContext(ThemeContext)
  return (
    <div>
      <p>current theme: {theme}</p>
    </div>
  )
}

function App() {
  const [theme, setTheme] = useState('light')
  return (
    <ThemeContext.Provider value={theme}>
      <button
        className={theme}
        onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
      >
        Toggle
      </button>
      <Page />
    </ThemeContext.Provider>
  )
}

export default App

鑒于淺色主題設置為 ThemeContext 中的默認主題,此測試將按預期通過。我們甚至可以測試第一個示例,但是,當我們對黑暗主題感興趣時,第二個測試中的事情會變得有趣。為了進入黑暗主題,我們需要開始使用測試替身,因為我們依賴于 ReactJS 上下文來做到這一點。第二個測試將 vi.mock 和 vi.mocked 混合在一起。請注意,要編寫的第二個測試也需要更改第一個測試。

import { render, screen } from '@testing-library/react'
import { Page } from './Page'

describe('<Page />', () => {
  it('should render light as default theme', () => {
    render(<Page />)
    expect(screen.getByText('current theme: light')).toBeInTheDocument()
  })
})

兩個測試用例現(xiàn)在都使用假的來測試驅(qū)動應用程序。如果我們改變上下文的返回數(shù)據(jù),測試也會改變。這里的注意點是:

  • 我們正在嘲笑reactjs上下文,這違背了“不要嘲笑你不擁有的東西”的原則
  • 測試變得更加冗長,因為我們需要使用模擬來做到這一點
  • 我們編寫的兩個測試沒有反映用戶與應用程序的交互。我們知道,當按下切換按鈕時,主題將會改變。

本節(jié)中使用的完整代碼可在 GitHub 上獲取

沒有測試替身

下一個方法是使用嵌入到我們的應用程序中的上下文,而不隔離它或使用任何測試替身。如果我們采用 TDD 的這種方法,我們可以從一個非常簡單的測試開始,模擬用戶的行為方式:

import { render, screen } from '@testing-library/react'
import { Page } from './Page'
import { useContext } from 'react'

vi.mock('react', () => {
  return {
    ...vi.importActual('react'),
    useContext: vi.fn(),
    createContext: vi.fn()
  }
})

describe('<Page />', () => {
  it('should render light as default theme', () => {
    vi.mocked(useContext).mockReturnValue('light')
    render(<Page />)
    expect(screen.getByText('current theme: light')).toBeInTheDocument()
  })

  it('should render dark theme', () => {
    vi.mocked(useContext).mockReturnValue('dark')
    render(<Page />)
    expect(screen.getByText('current theme: dark')).toBeInTheDocument()
  })
})

然后進行第二個測試,我們希望默認設置燈光主題:

import { render, screen } from '@testing-library/react'
import App from './App'
import userEvent from '@testing-library/user-event'

describe('<App />', () => {
  it('should render toggle button', () => {
    render(<App />)
    expect(screen.getByText('Toggle')).toBeInTheDocument()
  })
})

最后但并非最不重要的主題切換:

import { render, screen } from '@testing-library/react'
import App from './App'
import userEvent from '@testing-library/user-event'

describe('<App />', () => {
  it('should render toggle button', () => {
    render(<App />)
    expect(screen.getByText('Toggle')).toBeInTheDocument()
  })

  it('should render light as default theme', () => {
    render(<App />)
    expect(screen.getByText('current theme: light')).toBeInTheDocument()
  })
})

本攻略注意點:

  • 不需要測試替身,它可以用更少的代碼進行測試
  • 測試的行為與用戶在真實應用程序中的行為相匹配

本節(jié)中使用的完整代碼可在 GitHub 上獲取

每種方法的優(yōu)缺點

在本節(jié)中,我們將討論每種方法針對不同屬性的優(yōu)缺點。

重構(gòu) props

在上下文中使用測試替身會使測試對于這種更改變得脆弱。使用 props 重構(gòu) useContext 的使用會自動使測試失敗,即使行為沒有失敗。使用不使用測試雙精度的選項支持在這個意義上的重構(gòu)。

創(chuàng)建自定義上下文

使用自定義上下文而不是直接依賴reactjs 的上下文提供程序也會發(fā)生同樣的情況。使用不帶測試替身的選項可以進行重構(gòu)。

結(jié)論

在本指南中,我們探索了如何測試依賴于上下文的組件,而不需要測試替身,使測試更加簡單,更接近真實的用戶交互,并對比每種方法的優(yōu)缺點。只要有可能,就應遵循反映用戶交互的簡單方法。然而,當需要測試替身時,應該以測試代碼的可維護性為目標來使用它們。通過簡單的測試可以放心地重構(gòu)生產(chǎn)代碼。

資源

  • 創(chuàng)建自定義上下文
  • 重構(gòu)目錄
  • 用于查找如何使用 vitest 模擬模塊的特定部分
  • 用于查找如何解決類型問題
  • 測試庫 userEvent

下一步

  • 嘗試測試涉及多個上下文或嵌套提供程序的更復雜的場景。
  • 雖然我們在本指南中避免了模擬,但在某些情況下模擬是必要的。探索這些場景的高級模擬技術。

通過遵循這些步驟,您可以繼續(xù)提高測試技能并確保您的 React 應用程序可以重構(gòu)。

以上是測試 ReactJS 上下文 - 測試替身指南的詳細內(nèi)容。更多信息請關注PHP中文網(wǎng)其他相關文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權(quán)歸原作者所有,本站不承擔相應法律責任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語言,各自適用于不同的應用場景。Java用于大型企業(yè)和移動應用開發(fā),而JavaScript主要用于網(wǎng)頁開發(fā)。

JavaScript評論:簡短說明 JavaScript評論:簡短說明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時間處理需注意以下幾點:1.創(chuàng)建Date對象有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區(qū)問題建議使用支持時區(qū)的庫,如Luxon。掌握這些要點能有效避免常見錯誤。

為什么要將標簽放在的底部? 為什么要將標簽放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript與Java:開發(fā)人員的全面比較 JavaScript與Java:開發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

什么是在DOM中冒泡和捕獲的事件? 什么是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標元素,冒泡是從目標元素向上傳播到頂層。1.事件捕獲通過addEventListener的useCapture參數(shù)設為true實現(xiàn);2.事件冒泡是默認行為,useCapture設為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委托,提高動態(tài)內(nèi)容處理效率;5.捕獲可用于提前攔截事件,如日志記錄或錯誤處理。了解這兩個階段有助于精確控制JavaScript響應用戶操作的時機和方式。

JavaScript:探索用于高效編碼的數(shù)據(jù)類型 JavaScript:探索用于高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

Java和JavaScript有什么區(qū)別? Java和JavaScript有什么區(qū)別? Jun 17, 2025 am 09:17 AM

Java和JavaScript是不同的編程語言。1.Java是靜態(tài)類型、編譯型語言,適用于企業(yè)應用和大型系統(tǒng)。2.JavaScript是動態(tài)類型、解釋型語言,主要用于網(wǎng)頁交互和前端開發(fā)。

See all articles