2. React Testing Library
React Testing Library
given - when - then ํจํด
Mocking
Test fixture
๊ฐ์ ์ ๋ฆฌ
React Testing Library
๋ฆฌ์กํธ ํ ์คํธ๋ฅผ ์ฝ๊ฒํ ์ ์๋๋ก ๋ง๋ ๊ฒ ์ฌ์ฉ์ ์ ์ฅ์ ๊ฐ๊น๊ฒ ํ ์คํธํ ์ ์๋ค.
test๋ testํด๋๋ฅผ ๋ฐ๋ก ๋ง๋ค์๋ ์๊ณ ๊ฐ์ ๊ณ์ธต์ [filename].test.tsx ์ด๋ ๊ฒ ํ์ผ์ ๋ง๋ค์๋ ์๋ค.
import { render, screen } from '@testing-library/react';
import TextField from './TextField';
test('TextField', () => {
const text = 'Tester';
const setText = () => {
// do nothing...
};
render(
<TextField
label="Name"
placeholder="Input your name"
text={text}
setText={setText}
/>,
);
screen.getByLabelText('Name');
});
ํ ์คํธ ์ฝ๋, ์ฆ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ฉด์ ํด๋น ์ปดํฌ๋ํธ์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ฒํ ์ ์๋ค. ๊ธฐ์กด์๋ label์ด ๋น ์ ธ์์๊ณ , text ๊ฐ์ด ๋ฒ์ฉ์ ์ธ ํํ์ ์ฌ์ฉํ์ง ์์ ๋ฌธ์ ๊ฐ ์์๋ค. ๊ฐ๋ฐํ๋ฉด์ ์ด๋ฐ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ ์๋ ์์ง๋ง, ์ฐ๋ฆฌ๊ฐ ํ ์คํธ๋ถํฐ ์์ฑํ๊ฑฐ๋ ๋น ๋ฅด๊ฒ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ค๋ฉด ์์ฑํ๊ธฐ ์ ๋๋ ๋ฐ๋ก ์งํ์ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํด์ ์์ ํ ์ ์์์ ๊ฒ. ์๊ฐ์ด ์ง๋๋ฉด ํด๋น ์ฝ๋์ ๋ํ ์ง์์ด ๊ฐ์ํ๊ณ , ์์ ๊ฐ ๋ํ ๊ฐ์ํ๊ธฐ ๋๋ฌธ์ ๊ฑด๋๋ฆฌ๊ธฐ ํ๋ ์ฝ๋๊ฐ ๋๊ธฐ ์ญ์์ด๋ค.
ํ ์คํธ ์ฝ๋์์๋ ์ค๋ณต์ ์ ๊ฑฐํ๋ ๊ฒ์ด ์ค์ํ๋ค.
ํ ์คํธ๋ฅผ ์์ฑํ ๋ ์ธ๋ถ ์์กด์ฑ์ด ๊ฐํ ํจ์๊ฐ ์๋ค๋ฉด mocking์ ์ด์ฉํ ์ ์๋ค. jest mock BDD ์คํ์ผ๋ก ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ ์ฝ๊ธฐ ์ฝ๋ค. ํ ์คํธ ์ฝ๋๋ ์ฝ๋๋ค. ๋น์ฆ๋์ค ๋ก์ง๊ฐ์ ๋ถ๋ถ, ์๋ฅผ ๋ค์ด input์ ์ซ์๋ง ์ ๋ ฅ๋ฐ๊ณ ์ถ๋ค๋ฉด ์ด ๋ถ๋ถ์ ์ธ๋ถ์์ ์ฃผ์ ๋ฐ๊ฒ ํ๋ค. ์ปดํฌ๋ํธ๊ฐ ๋น์ฆ๋์ค ๋ก์ง์ ์ฑ ์์ ๊ฐ์ง ์๊ฒ ํ๋ค. ๋ฐ๋ผ์ ํจ์๊ฐ ํธ์ถ๋์๋์ง๋ง ํ์ธํ๋ฉด ๋๋ค.
import { render, screen, fireEvent } from '@testing-library/react';
import TextField from './TextField';
const context = describe;
describe('TextField', () => {
const text = 'Tester';
const setText = jest.fn();
beforeEach(() => {
setText.mockClear();
// ๋๋ jest.clearAllMocks();
});
function renderTextField() {
render(
<TextField
label="Name"
placeholder="Input your name"
text={text}
setText={setText}
/>,
);
}
it('renders an input control', () => {
renderTextField();
screen.getByLabelText('Name');
});
context('when user types text', () => {
it('calls the change handler', () => {
renderTextField();
fireEvent.change(screen.getByLabelText('Name'), {
target: {
value: 'New Name',
},
});
expect(setText).toBeCalledWith('New Name');
});
});
});
์ธ๋ถ ์์กด์ฑ์ด ํฐ ํจ์๋ ๋ชจํน์ ํ๋ค.
import { render, screen } from '@testing-library/react';
import App from './App';
jest.mock('./hooks/useFetchProducts', () => () => [
{
category: 'Fruits', price: '$1', stocked: true, name: 'Apple',
},
]);
test('App', () => {
render(<App />);
screen.getByText('Apple');
ํ
์คํธ ์ฝ๋์์ ์ฐ์ด๋ ๋๋ฏธ ๋ฐ์ดํฐ๋ฅผ fixture๋ผ๊ณ ํ๋๋ฐ fixtures
๋ผ๋ ํด๋๋ฅผ ๋ง๋ค์ด์ ๊ด๋ฆฌํ๋ค. hook์ mockingํ๋ ๊ฒฝ์ฐ์๋ ์ฒ์์๋ ํ
์คํธ ์ฝ๋ ๋ด๋ถ์ ์์ฑํ ์ ์์ง๋ง, ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด ๋ณต์กํด์ง๋ค. hooks/__mocks__
ํด๋์์ ๋ชจํน์ ํด๋๊ณ ์ธ๋ถ๋ก exportํ์ฌ ์ฌ์ฉํ๋ค.
TDD๋ ๋ง์ ์ฐ์ต์ด ํ์ํ๋ค. ์ถฉ๋ถํ ์๋ จ๋ ๋๊น์ง ์๋ จ์ด ํ์ํจ.
Last updated