はじめに
バックエンドに続いてフロントエンドのテストも導入したので、簡単にまとめておきたいと思います。
テストの流れ
①テスト対象のコンポーネントをレンダリング
②レンダリングするとDOMが生成されるのでテスト箇所のidを探しに行く(data-testidを付与しておく)
③testing-libraryのuserEventを使ってユーザアクションを実施
④実施したことで書き換わったDOMをベースに、期待するテストを実施
テストのコード(例)
frontend/__tests__/new_spec.jsx
import { render, screen, waitFor, cleanup, fireEvent } from '@testing-library/react';
import { toast } from 'react-toastify';
import '@testing-library/jest-dom'
import userEvent from '@testing-library/user-event'
import App from '../pages/new';
const textfile = new File(['これはファイル内容です'], 'test.txt', {
type: 'text/plain',
});
describe('ファイルをアップロードしたとき', () => {
afterEach(() => {
cleanup();
toast.warning.mockClear();
});
it('ファイル名が表示されること', async () => {
render(<App />);
const fileInput = screen.getByTestId('testfile-upload');
userEvent.upload(fileInput, textfile);
await waitFor(() => {
const spanElement = screen.getByTestId('uploaded-testfile');
expect(spanElement).toBeInTheDocument();
});
});
it('txt以外のファイルはエラーになること', async () => {
render(<App />);
const imgfile = new File(['テストファイル'], 'image.png', {
type: 'image/png',
});
const fileInput = screen.getByTestId('testfile-upload');
fireEvent.change(fileInput, { target: { files: [imgfile] } });
await waitFor(() => {
expect(toast.warning).toHaveBeenCalledWith(
'エラーメッセージ',
expect.anything()
);
});
});
it('ファイル内容確認のためのモーダルが表示されること', async () => {
render(<App />);
const fileInput = screen.getByTestId('testfile-upload');
userEvent.upload(fileInput, textfile);
await waitFor(() => {
expect(document.getElementById('confirmHundleTestFile')).toBeInTheDocument();
expect(screen.getByText('ファイルアップロード')).toBeInTheDocument();
expect(screen.getByText('これはファイル内容です')).toBeInTheDocument();
});
})
})
おわりに
フロントエンドのテストは初めて学んだのですが苦ではなかったので楽しいかもしれないです。テストの導入やテスト対象のファイルを読み込むまでにかなり苦戦したので、もしかしたらその反動かもしれませんが…
もっと良い書き方や考え方があると思いますので適宜インプットしていければと思います。