Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
モックわからないマン卒業記 ~振る舞いを起点に見直した、フロントエンドテストにおけるモックの使...
Search
Tasuku Watanabe
March 13, 2026
Programming
600
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
モックわからないマン卒業記 ~振る舞いを起点に見直した、フロントエンドテストにおけるモックの使いどころ~
Tasuku Watanabe
March 13, 2026
More Decks by Tasuku Watanabe
See All by Tasuku Watanabe
useImperativeHandleで理解する クロージャと評価タイミング
tasukuwatanabe
1
120
axiosで作る:ファイルアップロード体験を改善する「Progress Toast」
tasukuwatanabe
0
640
Other Decks in Programming
See All in Programming
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
290
AI時代のシニアエンジニアとは
yosuke_furukawa
PRO
12
11k
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
220
R8 の設定見直しでアプリサイズ削減
andpad
0
230
続・コーディングルールの鮮度を保ちたい / keep-fresh-go-internal-conventions-again
handlename
0
150
AI Augmentation Techniques with Liberty
ivargrimstad
0
150
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
1.2k
Apple Intelligenceとオンデバイス時代の到来
yahir0
0
170
Performance Optimization With LLMs
xleitix
0
230
Jetpack Compose Mechanisms
skydoves
3
900
graphql-ruby を Spinel で速くしようとした話
mtsmfm
0
130
Kotlinize Is Not Just Converting to Kotlin
chigichan24
1
200
Featured
See All Featured
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3.2k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
2
2.1k
Six Lessons from altMBA
skipperchong
29
4.5k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
Site-Speed That Sticks
csswizardry
13
1.6k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.4k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
47k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
600
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
550
Believing is Seeing
oripsolob
1
260
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
290
Transcript
モックわからないマン卒業記 振る舞いを起点に見直した、フロントエンドテストにおけるモックの使いどころ HRBrain 渡邉佑 2026-03-13 React Tokyo #14
自己紹介 渡邉 佑 ・HRBrain ・新潟県佐渡島出身 ・新卒で航海士→エンジニア ・PlaywrightでE2Eテスト実装中 ・X: @tasuku_web 2
フロントでテストを書く デグレを発生させず安心して機能開発したい AIでたくさんリファクタリングしたい。 → Vitest + React Testing Library でテストを書いている。
import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { Counter } from "./Counter"; test("ボタンをクリックするとカウントが増える", async () => { render(<Counter />); await userEvent.click(screen.getByRole("button", { name: "増やす" })); expect(screen.getByText("1")).toBeInTheDocument(); }); 3
モックという概念が登場 テストを書こうとすると、コンポーネント内部に外部の依存が潜んでいる。 function UserGreeting() { // propsや引数ではなく、コンポーネントが内部で直接参照している外部の値(= 外部依存) const {
data } = useFetchUser(); // API通信 const now = useCurrentTime(); // 現在時刻 const { userId } = useAuth(); // 認証状態 } 4
モックを使わないと何が起きるか テスト対象のコンポーネント APIを内部で呼び出しているコンポーネント export function UserGreeting() { // API通信が内部で走る const
{ data } = useFetchUser(); if (!data) return <p>読み込み中...</p>; return <p>こんにちは、{data.name} さん</p>; } モックなし:テストが書けない ・ネットワーク環境に依存する ・テストが遅い・不安定 ・エラー系など特定ケースの再現が難しい test("ユーザー名が表示される", async () => { render(<UserGreeting />); // 実際のAPIが走る → ネットワーク環境がなければ失敗する expect(await screen.findByText("こんにちは、Alice さん") }); 5
モックで依存を差し替えてテスト可能 ・ネットワーク不要・高速 ・テストしたいケースを自由に再現できる ・外部サービスの状態に左右されない import * as hooks from "./useFetchUser";
test("ユーザー名が表示される", async () => { vi.spyOn(hooks, "useFetchUser").mockReturnValue({ data: { name: "田中" }, }); render(<UserGreeting />); expect(screen.getByText("こんにちは、田中 さん")).toBeInTheDocument(); }); 6
実際のテストファイルではこうなりがち // ① モジュールモック vi.mock("./useRouter"); vi.mock("./useAuth"); // ② HTTPモック(MSW) const
server = setupServer( http.get("/api/users", () => HttpResponse.json([{ name: "田中" }])), ); beforeAll(() => server.listen()); afterAll(() => server.close()); beforeEach(() => { vi.useFakeTimers(); // ③ タイマーモック vi.setSystemTime(new Date("2026-01-01")); vi.mocked(useRouter).mockReturnValue({ push: vi.fn() }); vi.mocked(useAuth).mockReturnValue({ userId: "u1" }); }); test("ユーザー一覧が表示される", async () => { const onSelect = vi.fn(); // ④ モック関数 render(<UserListPage onSelect={onSelect} />); expect(await screen.findByText("田中")).toBeInTheDocument(); }); 7
「APIが呼ばれたこと」を検証するのはNG ❌ よくある検証 import { fetchUsers } from "./api"; vi.mock("./api");
test("ユーザー一覧を取得する", () => { render(<UserListPage />); // APIが呼ばれたことを確認 expect(fetchUsers).toHaveBeenCalledWith("/api/users"); }); なぜNGか ・URLが /api/v2/users に変わるだけで壊れる ・画面が正しく表示されていてもテストが失敗する = リファクタリングのたびにテストも壊れる 8
だから、振る舞いをテストする
「振る舞いをテストする」という考え方 確認すべきは「何が呼ばれたか」より「画面がどう振る舞うか」 // 実装を見る(useStateの更新を直接確認) expect(setCount).toHaveBeenCalledWith(1); // 振る舞いを見る(画面がどう変わるかを確認) expect(screen.getByText("1")).toBeInTheDocument(); ・内部実装を変えても壊れにくい( setCount
→ useReducer に変えてもテストはパスする) ・ユーザーの視点でテストを書ける(ユーザーが気にするのは画面の動作であり、内部実装ではない) ・テストが仕様書になる( 「この操作をするとこう表示される」という意図が明確になる) 10
「振る舞いをテストする」という考え方 API通信: 「fetchが呼ばれたか」より「結果が表示されるか」 // 実装を見る(fetchの呼び出しを直接確認) expect(mockFetch).toHaveBeenCalledWith("/api/users"); // 振る舞いを見る(取得したデータが画面に表示されるかを確認) expect(screen.getByText("田中太郎")).toBeInTheDocument(); ・
実装依存: fetch の呼び出し先URL が変わるだけでテストが壊れる。コンポーネントの「結果」 は正しくても失敗する ・ 振る舞いベース:URLが変わっても、別のライブラリに乗り換えても、画面に結果が出ればテスト はパスする 11
「振る舞いをテストする」という考え方 ルーティング: 「router.pushが呼ばれたか」より「画面が遷移したか」 // 実装を見る(router.pushの呼び出しを直接確認) expect(mockPush).toHaveBeenCalledWith("/dashboard"); // 振る舞いを見る(遷移後のページが表示されるかを確認) expect( screen.getByRole("heading",
{ name: "ダッシュボード" }), ).toBeInTheDocument(); 12
まとめ モックで外部依存を差し替える → テストが書けるようになる API通信・認証・時刻などを固定してテスト可能に でも多用すると、リファクタリング耐性が下がる 実装詳細(関数名・モジュール構造)に依存し、テストが壊れやすくなる だから、振る舞い(画面の動作)をテストする 「何が呼ばれたか」より「画面がどう変わるか」を確認する 13
ご清聴ありがとうございました