React Testing Library 일반적인 테스트 시나리오
Install Packages
npm install --save-dev @testing-library/react @testing-library/jest-dom
DOM 요소 테스트
App.js 파일
// App.js
import React from "react";
export const App = () => {
return <h1 data-testid="big-title">Hello React</h1>
}
App.test.js 파일
// App.test.js
import React from "react";
import { render, screen } from "@testing-library/react";
import { App } from "./App";
describe("App", () => {
test("renders App component", () => {
render(<App />);
// 제목의 Dom 요소가 존재하는지 여부를 확인하는 다양한 방법
expect(screen.getByRole("heading")).toHaveTextContent("Hello React");
expect(screen.getByRole("heading", { name: "Hello React" })).toBeInTheDocument();
expect(screen.getByText("Hello React")).toBeInTheDocument();
expect(screen.getByTestId("big-title")).toHaveTextContent("Hello React");
// 존재하지 않는 Dom 요소에 대한 쿼리
expect(screen.queryByTestId("another-big-title")).toBeNull();
});
});
테스트 라이브러리는 DOM 요소를 가져오는 여러 가지 메서드를 제공하며, 우선 순위는 다음과 같은 세 가지 일반적인 범주에 속합니다.
- 쿼리
- getByRole
- etByLabelText
- getByPlaceholderText
- getByText
- getByDisplayValue
- 시맨틱 쿼리
- getByAltText
- getByTitle
- Test IDs
- getByTestId
테스트 이벤트
App.js 파일
// App.js
import React from "react";
export const App = ({ handleChange }) => {
return (
<div>
<label htmlFor="search">Search</label>
<input
id="search"
type="text"
value="Search"
onChange={handleChange}
/>
</div>
)
}
App.test.js 파일
// App.test.js
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { App } from "./App";
describe("App", () => {
test("renders App component", () => {
const mockSearchFunc = jest.fn();
// Render
render(<App handleChange={mockSearchFunc}/>);
// Act
fireEvent.change(screen.getByRole("textbox"));
// Asset
expect(mockSearchFunc.call.length).toBe(1);
});
});
컴포넌트의 이벤트를 테스트하려면 먼저 이벤트를 모킹한 다음 화면의 메서드로 요소를 선택하고, fireEvent로 이벤트 구현을 시뮬레이션한 다음 마지막으로 어설트해야 합니다.
fireEvent는 변경, 클릭, 포커스 등과 같은 일반적인 이벤트를 구현할 수 있습니다.
비동기 이벤트 - await
App.js 파일
// App.js
import React from "react";
const getUser = () => {
return Promise.resolve({ id: "1", name: "Robin" });
};
export const App = () => {
const [user, setUser] = React.useState(null);
React.useEffect(() => {
const loadUser = async () => {
const user = await getUser();
setUser(user);
};
loadUser();
}, []);
return (
<div>
{user ? <p>Signed in as {user.name}</p> : null}
</div>
);
}
App.test.js 파일
// App.test.js
import React from "react";
import { render, screen } from "@testing-library/react";
import { App } from "./App";
describe("App", () => {
test("renders App component", async () => {
// Render
render(<App />);
// At first, the dom is not exist
expect(screen.queryByText(/Signed in as/)).toBeNull();
// Later, when function exec, the dom is appeared
expect(await screen.findByText(/Signed in as/)).toBeInTheDocument();
});
});
find* 메서드는 비동기 호출 후 Dom 요소를 찾는 데 적합하며 await과 함께 사용됩니다.
비동기 이벤트 - 요청된 데이터가 포함된 컴포넌트 테스트
App.js 파일
// App.js
import React from 'react';
import axios from 'axios';
const URL = 'http://xxx/api/v1/search';
export const App = () => {
const [stories, setStories] = React.useState([]);
const [error, setError] = React.useState(null);
async function handleFetch(event) {
let result;
try {
result = await axios.get(`${URL}?query=React`);
setStories(result.data.hits);
} catch (error) {
setError(error);
}
}
return (
<div>
<button type="button" onClick={handleFetch}>
Fetch Stories
</button>
{error && <span>Something went wrong ...</span>}
<ul>
{stories.map((story) => (
<li key={story.objectID}>
<a href={story.url}>{story.title}</a>
</li>
))}
</ul>
</div>
);
}
App.test.js 파일
// App.test.js
import React from 'react';
import axios from 'axios';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import App from './App';
jest.mock('axios');
describe('App', () => {
test('fetches stories from an API and displays them', async () => {
const stories = [
{ objectID: '1', title: 'Hello' },
{ objectID: '2', title: 'React' },
];
axios.get.mockImplementationOnce(() =>
Promise.resolve({ data: { hits: stories } })
);
render(<App />);
await userEvent.click(screen.getByRole('button'));
const items = await screen.findAllByRole('listitem');
expect(items).toHaveLength(2);
});
});
대기 및 어설션을 통해 테스트 데이터를 반환하는 모의 액시오스 메서드 구현




