【React】使用Jest寫單元測試

更新 發佈閱讀 15 分鐘

先前環境設定

在使用 Jest 前需要先使用 npm 安裝:

npm install jest

使用指令:

 npm jest

使用內容

先來看一下大致長得怎樣😃

這是Header.jsx

// Header.jsx
import React from "react";

const Header = ({ heading, subHeading }) => {
return (
<section className="header">
<h1 data-testid="heading">{heading}</h1>
<p data-testid="subHeading">{subHeading}</p>
</section>
);
};

export default Header;

在來,針對Header.jsx,所寫寫的unit test:

// Header.test.jsx

import { render, screen } from "@testing-library/react";
import Header from "../Header";

describe("test header component", () => {
test("render the heading text", () => {
render(<Header heading="Word Counter" />);
const heading = screen.getByTestId("heading");
expect(heading.innerHTML).toBe("Word Counter");
});
});

完蛋看不懂,先讀GPT針對基本名詞的解析:

describe 是 Jest 中的一個函數,用於組織測試案例。它可以幫助你將相關的測試案例分組在一起,提高可讀性和組織性。
test 是 Jest 提供的函數,用於撰寫單一測試案例。它接受兩個參數:測試案例的描述,以及一個包含測試程式碼的函數。
test 為測試的最小單位,就是像是變數的宣告一樣,要攥寫每一筆測試時都需要使用 test 宣告。
render 是 @testing-library/react 提供的函數,用於渲染 React 組件。我們使用 render 渲染 Header 組件並傳遞 heading 屬性為 "Word Counter"。
screen 是 @testing-library/react 提供的物件,用於查詢渲染結果中的元素。
getByTestId 是用於查詢帶有特定 data-testid 屬性的元素。
expect 是 Jest 提供的斷言函數,用於進行測試斷言。

這樣是不是可以大概知道,先指定我要render的東西<Header/>,接著使用getByTestId去依照ID指定我要搜尋的標籤。

expect(heading.innerHTML).toBe("Word Counter");

是指“expect(目標).toBe(應該出現的內容);”

🥰這樣是不是清楚很多了,那接下來,我先做了一個畫面:

raw-image

這是一個可以計算文字數跟字元數的動態JS,那在jsx是長這樣:

import React, { useRef, useState } from "react";

const Counter = () => {
// ...
return (
<section className="counter">
<textarea
// ...
data-testid="textArea"
placeholder="Type or paste your text"></textarea>
<button
// ...
onClick={handleButton}
data-testid="clearBtn"
>
Clear
</button>

<p className="result">
<span data-testid="charLength">Character: {charLength}</span>
<span data-testid="wordLength">Word: {wordLength}</span>
</p>
</section>
);
};

export default Counter;

那我接下來在裡面輸入東西:

raw-image

針對這一項功能,我可以寫一隻測試如下:

import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import Counter from "../Counter";
import userEvent from "@testing-library/user-event";

test("change textarea and update result", () => {
render(<Counter />);
const textArea = screen.getByTestId("textArea");
const charLength = screen.getByTestId("charLength");
const wordLength = screen.getByTestId("wordLength");

// 模擬為東西進去
userEvent.type(textArea, "test123");
expect(charLength.innerHTML).toBe("Character: 7");
expect(wordLength.innerHTML).toBe("Word: 1");
});

去模擬我輸入“test123”,他應該要輸出什麼樣的內容。

那如果我想繼續:當我按下“clear“,裡面東西,字元數,文字數全部清空,那我就可以這樣寫:

import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import Counter from "../Counter";
import userEvent from "@testing-library/user-event";

test("clear change textarea and update result", () => {
render(<Counter />);
const textArea = screen.getByTestId("textArea");
const charLength = screen.getByTestId("charLength");
const wordLength = screen.getByTestId("wordLength");
const clearBtn = screen.getByTestId("clearBtn");

userEvent.click(clearBtn);
// 模擬案”click",後會誒出現的內容
expect(charLength.innerHTML).toBe("Character: 0");
expect(wordLength.innerHTML).toBe("Word: 0");
});


那如果是碰到fetch的測試,就是增加async跟waitFor:

import { getByTestId, render, waitFor } from "@testing-library/react";
import Joke from "../Joke";

describe("test joke component", async () => {
test("render joke test", () => {
render(<Joke />);
const jokeHeadline = getByTestId("jokeHeadline");
await waitFor(() => {
expect(jokeHeadline.innerHTML).toBeTruthy();
});
});
}); 


🙂接下來,介紹wrapper:

一樣先看GPT的解釋:

以下是 wrapper 的用法和目的:

- 包裹渲染組件: 在測試中,你通常會使用測試工具庫提供的函數(如 Enzyme 的 shallow 或 mount,Vue Test Utils 的 mount)來渲染組件。這些函數將組件渲染成虛擬 DOM,同時返回一個稱為 wrapper 的對象,它代表著包裹了渲染結果的容器。

- 查詢、操作和斷言: wrapper 對象通常提供了許多方法,這些方法讓你能夠查詢虛擬 DOM 中的元素、訪問組件的屬性和狀態,甚至模擬用戶互動。你可以使用這些方法來進行斷言、操作元素,並驗證組件的行為是否符合預期。

- 斷言測試結果: 通過 wrapper,你可以斷言組件的渲染結果是否與預期相符。你可以使用 wrapper 提供的方法查詢特定的元素,然後使用斷言方法(如 Jest 的 expect)來驗證渲染結果是否符合預期。

總之,wrapper 是一個用於包裹渲染組件並提供測試工具庫所需方法的對象。它使你能夠進行測試,驗證組件的渲染、行為和狀態是否如預期。請注意,wrapper 的用法和方法可能因測試工具庫而異,所以具體的實現方式可能會根據你使用的工具庫有所不同。

講那麼多,其實大概可以看出來是做來渲染的。
舉例來說,像是我們在使用router的情境下:

function App() {
return (
<div className="App">
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/joke" element={<JokePage />} />
<Route path="*" element={<PageNotFound />} />
</Routes>
</div>
);
}

export default App;

如果我要針對PageNotFound去寫測試:

import { render } from "@testing-library/react";
import PageNotFound from "../PageNotFound";
import { BrowserRouter } from "react-router-dom";

describe("test PageNotFound Page", () => [
test("render text and image", () => {
// 因為PageNotFound有被BrowserRouter渲染過,因此要在render中增加wrapper參數
const { getByTestId, getByAltText } = render(<PageNotFound />, {
wrapper: BrowserRouter,
});
const pnfText = getByTestId("pnfText");
expect(pnfText.innerHTML).toBe("Oops - Page Not Found!");
}),
]);
留言
avatar-img
W. C. Chen的沙龍
4會員
10內容數
你可能也想看
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
創業者常因資金困境而無法抓住機會,利用房產活化讓二胎房貸成為財務策略的有力夥伴。 諮詢國峯厝好貸的二胎房貸服務,讓你的房子成為你最強力的天使投資人,推動事業成長。
Thumbnail
創業者常因資金困境而無法抓住機會,利用房產活化讓二胎房貸成為財務策略的有力夥伴。 諮詢國峯厝好貸的二胎房貸服務,讓你的房子成為你最強力的天使投資人,推動事業成長。
Thumbnail
本章節將引導你如何建立一個TypeScript開發環境,這包括安裝Node.js、npm和TypeScript,建立一個TypeScript項目,設置編輯器,以及編寫和編譯TypeScript代碼。在完成這些步驟之後,你將能夠編寫、編譯和運行TypeScript代碼。
Thumbnail
本章節將引導你如何建立一個TypeScript開發環境,這包括安裝Node.js、npm和TypeScript,建立一個TypeScript項目,設置編輯器,以及編寫和編譯TypeScript代碼。在完成這些步驟之後,你將能夠編寫、編譯和運行TypeScript代碼。
Thumbnail
本章目的是為讀者提供有關如何設置JavaScript開發環境的知識,包括在瀏覽器、Node.js和各種編輯器和IDE中編寫和運行JavaScript的信息。此外,本章還介紹了如何架設本地開發伺服器以模擬實際的網頁環境。這些知識對於希望開發前端應用或後端服務的JavaScript開發者來說都是必要的。
Thumbnail
本章目的是為讀者提供有關如何設置JavaScript開發環境的知識,包括在瀏覽器、Node.js和各種編輯器和IDE中編寫和運行JavaScript的信息。此外,本章還介紹了如何架設本地開發伺服器以模擬實際的網頁環境。這些知識對於希望開發前端應用或後端服務的JavaScript開發者來說都是必要的。
Thumbnail
在程式任何地方都能修改各種react組件狀態的做法分享
Thumbnail
在程式任何地方都能修改各種react組件狀態的做法分享
Thumbnail
Express 是一個流行的 web 框架,使用 JavsScript 實現,執行在 node 環境上,主要用來寫後端應用。
Thumbnail
Express 是一個流行的 web 框架,使用 JavsScript 實現,執行在 node 環境上,主要用來寫後端應用。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News