🐡

VitestでReactのテストを書いてみる

2023/11/13に公開

はじめに

Vitestを使ってReactのテストを作成します。
ひとまずサンプルとしてボタンのコンポーネントを作成します。

Viteでプロジェクトを作成する

プロジェクトがなければ作成します。

npm create vite@latest

ライブラリインストール

テスト系ライブラリのインストール

npm install -D vitest jsdom @testing-library/react @testing-library/jest-dom @testing-library/user-event @types/testing-library__user-event

設定追加

以下のファイルを作成します。

vitest.config.ts
/// <reference types="vitest" />
import react from "@vitejs/plugin-react";
import { defineConfig } from "vitest/config";
import * as path from "path";

export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: "jsdom",
    include: ["src/**/*.test.{js,ts,jsx,tsx}"],
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
});

コンポーネントの作成

簡単なボタンを作ります。

src/components/parts/Button/Button.tsx
export default function Button({
  children,
  onClick,
  disabled,
}: {
  children?: React.ReactNode;
  onClick?: React.MouseEventHandler<HTMLButtonElement>;
  disabled?: boolean;
}) {
  return (
    <button disabled={disabled} style={{ backgroundColor: "white" }} onClick={onClick}>
      {children}
    </button>
  );
}
src/components/parts/index.ts
export { default } from "./Button";

テストの作成

ひとまずこんな感じのテストを作成してみます。

  • 中に入れた文字列が表示させること
  • コンポーネントがボタンであること
  • ボタンを押したらonClickの関数が実行されること
  • disabledをtrueにしたらボタンをクリック出来ないこと
tsx
import "@testing-library/jest-dom";
import { fireEvent, render, screen } from "@testing-library/react";
import { expect, test, vi } from "vitest";

import Button from ".";

test("Buttonに文字が表示されること", async () => {
  render(<Button>Button</Button>);

  expect(screen.getByText("Button")).toBeTruthy();
});

test("Buttonロールであること", async () => {
  render(<Button>Button</Button>);

  expect(screen.getByRole("button").textContent).toBe("Button");
});

test("クリックするとonClick()が実行されること", async () => {
  const onClickMock = vi.fn(() => {});

  render(<Button onClick={onClickMock}>Button</Button>);
  expect(onClickMock).toHaveBeenCalledTimes(0);

  const button = screen.getByRole("button");
  await fireEvent.click(button);

  expect(onClickMock).toHaveBeenCalledTimes(1);
  await fireEvent.click(button);
  expect(onClickMock).toHaveBeenCalledTimes(2);
});

test("ボタンの背景色がしろであること", async () => {
  render(<Button>Button</Button>);
  const button = screen.getByRole("button");

  expect(button).toHaveStyle("background-color: rgb(255, 255, 255)");
});

test("disabledをtureにするとボタンがクリック出来なくなること", async () => {
  const onClickMock = vi.fn(() => {});

  render(
    <Button disabled={true} onClick={onClickMock}>
      Button
    </Button>
  );

  const button = screen.getByRole("button");
  await fireEvent.click(button);

  expect(onClickMock).toHaveBeenCalledTimes(0);
});

テストを実行する

npm run test


テストが通りました!

コラボスタイル Developers

Discussion