概要
@testing-library/reactを使ってモーダル実装したコードのテストコードを書いてみました。
仕様
実装内容としては、1つのページにモーダルを開くリンクと、初期状態がdisabledのボタンがあり
モーダルを開くリンクを押し、モーダルを閉じる際にボタンのdisabledを解除しボタンが押せるようにするというのが
実装ないようになります。
コード
App.tsx
import React, { useState } from "react";
import { ModalItem } from "./components/ModalItem";
export const App: React.FC = () => {
const [isOpen, setIsOpen] = useState(false);
const [disabled, setDisabled] = useState(true);
const handleOpenModal = () => {
setIsOpen(!isOpen);
};
const handleCloseModal = () => {
setDisabled(false);
setIsOpen(!isOpen);
};
return (
<div>
<p>ここはテスト用に作ったページです</p>
<span onClick={handleOpenModal}>ここを押すとモーダルが開きます</span>
<button disabled={disabled}>ここはボタンです</button>
<ModalItem isOpen={isOpen} handleClose={handleCloseModal} />
</div>
);
};
components/ModalItem.tsx
import React from "react";
import Modal from "@mui/material/Modal";
import "./index.css";
import { Box, Typography } from "@mui/material";
type Props = {
isOpen: boolean;
handleClose: () => void;
};
const style = {
position: "absolute" as "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: "background.paper",
border: "2px solid #000",
boxShadow: 24,
p: 4,
};
export const ModalItem: React.FC<Props> = ({ isOpen, handleClose }) => {
return (
<div>
<Modal open={isOpen} onClose={handleClose}>
<Box sx={style}>
<Typography>ここはモーダルです</Typography>
<button onClick={handleClose}>閉じる</button>
</Box>
</Modal>
</div>
);
};
上の仕様通りに作りました。
次はテストです。
App.test.tsx
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { App } from "./App";
test("モーダルが表示されること", () => {
render(<App />);
// モーダルを開くリンクが存在していること
const targetLink = screen.getByText("ここを押すとモーダルが開きます");
expect(targetLink).toBeInTheDocument();
// 初期状態のボタンがdisabledになっていること
const targetButton = screen.getByText("ここはボタンです");
expect((targetButton as HTMLButtonElement).disabled).toStrictEqual(true);
// モーダルを開いて、モーダルが表示されていることを確認
fireEvent.click(targetLink);
expect(screen.getByText("ここはモーダルです")).toBeInTheDocument();
// モーダルの閉じるボタンを押してモーダルが非表示になっていることを確認
fireEvent.click(screen.getByText("閉じる"));
expect(screen.queryByText("ここはモーダルです")).not.toBeInTheDocument();
expect((targetButton as HTMLButtonElement).disabled).toStrictEqual(false);
});
テストコードの解説
難しい部分はほとんどないのですが、
getByTextでアクションに必要な要素を取得しています。
queryByTextを使っている部分は、非表示の要素がないことを確認したい際に使用します。getByText.not.toBeInTheDocument()だと要素の取得ができないためテスト失敗します。
アクションしたい要素を取得したらfireEvent.click()でその要素をクリックすることができるので
そちらを使って簡単にテストができました。