2. React Testing Library

1. React Testing Library

React Testing Library ๊นƒํ—ˆ๋ธŒ React Testing Library ๊ณต์‹ ๋ฌธ์„œ jest-dom

๐Ÿ’ก React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉ์ž ์ž…์žฅ์— ๊ฐ€๊น๊ฒŒ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ UI ํ…Œ์ŠคํŠธ์— ํŠนํ™”๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ E2E Test์ฒ˜๋Ÿผ ์‚ฌ์šฉ ๊ฐ€๋Šฅ โ†’ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•˜๋“ฏ์ด ํ…Œ์ŠคํŠธ

๐Ÿ›  ๊ธฐ์กด์˜ ๋„๊ตฌ

enzyme ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ ๋ณด๋‹ค๋Š” ํ•ดํ‚นํ•˜๋Š” ๋Š๋‚Œ์œผ๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ๋˜์–ด ์žˆ์—ˆ์Œ React Testing Library๋„ ๊ตฌํ˜„ ์ž์ฒด๋Š” ํ•ดํ‚นํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋˜์–ด ์žˆ์ง€๋งŒ, ์‚ฌ์šฉ์ž ์ž…์žฅ์— ๊ฐ€๊น๊ฒŒ ๋งŒ๋“ค์–ด์ง

๐Ÿค“ React Testing Library๋Š”? ์›น ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„๋‹Œ ๊ณณ์—์„œ๋Š” document๋ฅผ ์“ธ ์ˆ˜ ์—†์ง€๋งŒ, ๊ทธ๋Ÿฐ ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์คŒ jest๋Š” node์—์„œ ๋Œ์•„๊ฐ€๋Š”๋ฐ React Testing Library๋Š” DOM ๊ด€๋ จ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ ์œ„์— react๋ฅผ ์–น์–ด์„œ ๋Œ๋ฆฌ๋ฉด ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ

const div = document.createElement('div')

์žฅ์ 

  • ๋น ๋ฅด๊ฒŒ ์ž‘๋™

  • ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค ์ž‘์„ฑ์ด ์‰ฌ์›€

render๋ฅผ ์ด์šฉํ•˜๋ฉด Main.tsx์˜ render์™€ ๋น„์Šทํ•˜์ง€๋งŒ ํ›จ์”ฌ ์‰ฝ๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

import {render} from '@testing-library/react';
// Main.tsx

root.render((
    <React.StrictMode>
        <App/>
    </React.StrictMode>
));

2. given - when - then ํŒจํ„ด

๋ชจ๋“  BDD ์‹œ๋‚˜๋ฆฌ์˜ค์— ์žˆ๋Š” 3๊ฐ€์ง€ ํ•ต์‹ฌ ์š”์†Œ

  • GIVEN (context, ๋ฌธ๋งฅ ์„ค๋ช…)

  • WHEN (action, ๋™์ž‘ ์„ค๋ช…) : ~ ํ•œ ๋™์ž‘์„ ํ•˜๋ฉด

  • THEN (outcome, ๊ฒฐ๊ณผ ์„ค๋ช…) : ~ ์ด๋ ‡๊ฒŒ ๋œ๋‹ค

context('with only one arguments', () => {
    it('returns the same numbers', () => {
        // When
        const result = add(2);

        // Then
        expect(add(2)).toBe(2);
    });
});

์ผ€์ด์Šค๋ฅผ ๋‚˜๋ˆ  ์ฝ”๋“œ๋ฅผ ์งœ๊ธฐ ๋•Œ๋ฌธ์— ํ‘œํ˜„๋ ฅ์ด ์ข‹์•„์ง€๊ณ , ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•  ์ˆ˜ ์žˆ์Œ

3. ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

๐Ÿ”— ์‹ค์Šต ๋งํฌ

์ฃผ์˜์ 

  1. ๐Ÿ’ก UI๋Š” ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ๋ฅผ ํ†ตํ•ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅ ๋ฒ”์šฉ์„ฑ์ด ์ปค์ง€๊ณ  ๋‹ค๋ฅธ ๊ณณ์—์„œ ํ„ฐ์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ฒ˜์Œ๋ถ€ํ„ฐ UI๋ฅผ ๋˜๋„๋ก ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•  ๊ฒƒ

  2. ๊ณต์šฉ ๋กœ์ง์„ ์ด˜์ด˜ํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ

  3. ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์€ ๋ชจ๋“ˆ์„ ๋ชจํ‚นํ•˜๊ฑฐ๋‚˜ ๋ฐฑ์—”๋“œ ๋ถ€๋ถ„์€ MSW๋ฅผ ์‚ฌ์šฉํ•ด ์ฒ˜๋ฆฌํ•˜๊ธฐ

์ปดํฌ๋„ŒํŠธ์˜ ์ธํ„ฐํŽ˜์ด์Šค ์ ๊ฒ€

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ(์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ)๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ ๊ฒ€ ๊ฐ€๋Šฅ

// TextField.test.tsx

import {render, screen} from '@testing-library/react';

import TextField from './TextField';

test('TextField', () => {
    // Given
    const text = 'Tester';
    const setText = () => {
        // do nothing...
    };

    // When
    render((
        <TextField
            label="Name"
            placeholder="Input your name"
            text={text}
            setText={setText}
        />
    ));

    // Then
    screen.getByLabelText('Name');
    screen.getByPlaceholderText(/name/);
    screen.getByDisplayValue(text);
});

๊ธฐ์กด์˜ ๋ฌธ์ œ

  • label์ด ๋น ์ ธ์žˆ๋Š” ๋ฌธ์ œ

  • text ๊ฐ™์ด ๋ฒ”์šฉ์ ์ธ ํ‘œํ˜„์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ๋ฌธ์ œ

ํ…Œ์ŠคํŠธ๋ถ€ํ„ฐ ์ž‘์„ฑํ–ˆ๊ฑฐ๋‚˜ ๋น ๋ฅด๊ฒŒ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค๋ฉด, ์ž‘์„ฑํ•˜๊ธฐ ์ „ ๋˜๋Š” ์งํ›„์— ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•ด์„œ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์—ˆ์„ ๊ฒƒ โš ๏ธ ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ํ•ด๋‹น ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ง€์‹์ด ๊ฐ์†Œํ•˜๊ณ , ์ž์‹ ๊ฐ๋„ ๊ฐ์†Œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฑด๋“œ๋ฆฌ๊ธฐ ํž˜๋“  ์ฝ”๋“œ๊ฐ€ ๋˜๋‹ˆ ์ฃผ์˜

BDD ์Šคํƒ€์ผ๋กœ ์ฝ”๋“œ ์ˆ˜์ •, ์ž…๋ ฅ ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ

BDD ์Šคํƒ€์ผ๋กœ ์ฝ”๋“œ๋ฅผ ๋ฐ”๊พธ๊ณ , ์ž…๋ ฅ ๋“ฑ์ด ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธ

1. context ๋ถ„๋ฆฌ

import {render, screen, fireEvent} from '@testing-library/react';

import TextField from './TextField';

const context = describe;

describe('TextField', () => {
    // Given
    const label = 'Name';
    const text = 'Tester';

    const setText = jest.fn(); // ๋ชจํ‚น

    it('renders elements', () => {
        // When
        render((
            <TextField
                label={label}
                placeholder='Input your name'
                text={text}
                setText={setText}
            />
        ));

        // Then
        screen.getByLabelText(label);
        screen.getByPlaceholderText(/name/);
        screen.getByDisplayValue(text);
    });

    context('when user enters name', () => {
        it('calls "setText" handler', () => {
            // Given
            render((
                <TextField
                    label={label}
                    placeholder='Input your name'
                    text={text}
                    setText={setText}
                />
            ));

            // When
            fireEvent.change(screen.getByLabelText(label), {
                target: {value: 'New Name'},
            });

            // Then
            expect(setText).toBeCalledWith('New Name');
        });
    });
});

2. render ํ•จ์ˆ˜ ์ƒ์„ฑ, ๋ชจํ‚น ํ•จ์ˆ˜ ์ดˆ๊ธฐํ™” ์ฒ˜๋ฆฌ

describe-context๋กœ ๋‚˜๋ˆ ์ค„์ˆ˜๋ก ์ˆ˜์›”ํ•˜๊ฒŒ ์ง„ํ–‰๋จ

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(); // โ†’ ํ•ด๋‹น ๋Œ€์ƒ๋งŒ clear
        // ๋˜๋Š” jest.clearAllMocks(); โ†’ ์ „๋ถ€ ๋‹ค clear
    });

    function renderTextField() {
        render((
            <TextField
                label="Name"
                placeholder="Input your name"
                text={text}
                setText={setText}
            />
        ));
    }

    function inputText(value: string) {
        fireEvent.change(screen.getByLabelText(label), {
            target: {value},
        });
    }

    it('renders an input control', () => {
        // When
        renderTextField();

        // Then
        screen.getByLabelText('Name');
    });


    context('when user enters name', () => {
        beforeEach(() => {
            // Given
            renderTextField();
        });

        it('calls "setText" handler', () => {
            // When
            inputText('New Name');

            // Then
            expect(setText).toBeCalledWith('New Name');
        });
    });
});
  • ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ Extract Function

  • fireEvent ๋“ฑ์„ ํ†ตํ•ด ์ธํ„ฐ๋ž™์…˜๋งŒ ๊ฒ€์ฆ

  • ๋งŒ์•ฝ ๋ณต์žกํ•œ ๋กœ์ง์ด ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ๋ถ„๋ฆฌ๋œ๋‹ค๋ฉด, ์—ฌ๊ธฐ์„œ๋Š” ์ด๊ฒƒ๋งŒ ๊ฒ€์ฆํ•˜๋ฉด ๋จ

    • Ex. setText์— ์ˆซ์ž๋งŒ ์ž…๋ ฅ๋ฐ›๊ฒŒ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ทธ๋Ÿฐ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ…Œ์ŠคํŠธ ํ•  ๋•Œ ๊ทธ๋ ‡๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก ์ž‘์„ฑํ•˜๋ฉด ๋จ

    • ๐Ÿ’ก ์ปดํฌ๋„ŒํŠธ์˜ ์ฑ…์ž„์ด ์•„๋‹ˆ๊ฒŒ ๋จ

API ์š”์ฒญ ์ฝ”๋“œ ๋ชจํ‚น

๐Ÿ”— ์‹ค์Šต ๋งํฌ

์™ธ๋ถ€ ์˜์กด์„ฑ์ด ํฐ ์ฝ”๋“œ(API ์š”์ฒญ ๋“ฑ)๋ฅผ ์ž‘์„ฑํ•  ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ถ€๋ถ„๋งŒ ๊ฐ€์งœ๋กœ ๊ตฌํ˜„

// App.test.tsx

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');
});

๋งค๋ฒˆ ์„œ๋ฒ„๋ฅผ ๋„์šฐ๊ธฐ ์–ด๋ ต๊ณ , ์‹ค์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ค์šด ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํ…Œ์ŠคํŠธ์—์„œ๋งŒ ๊ฐ€์งœ๋กœ ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ ํ”„๋ก ํŠธ์—”๋“œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐฑ์—”๋“œ์™€ ์†Œํ†ตํ•˜๋Š” ๋น„์ค‘์ด ํผ ๐Ÿ’ก ์ด ๋ถ€๋ถ„์„ ํ•˜๋‚˜์”ฉ ๊ฐ€์งœ ๊ตฌํ˜„์œผ๋กœ ๋ฐ”๊พธ๋‹ค ๋ณด๋ฉด ์–ด๋ ค์šด ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒ โ†’ MSW ๋“ฑ ๋‹ค๋ฅธ ๋Œ€์•ˆ์„ ๊ณ ๋ ค

4. Mocking

๋ชจ์˜ ๊ฐ์ฒด

๊ฐ€์งœ๋กœ ์ ๋Š” ๊ฒƒ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•  ๋ชจ๋“ˆ๊ณผ ์—ฐ๊ฒฐ๋˜๋Š” ์™ธ๋ถ€์˜ ๋‹ค๋ฅธ ์„œ๋น„์Šค๋‚˜ ๋ชจ๋“ˆ์„ ์‹ค์ œ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์‹ค์ œ์˜ ๋ชจ๋“ˆ์„ ํ‰๋‚ด๋‚ด๋Š” ๊ฐ€์งœ ๋ชจ๋“ˆ์„ ์ž‘์„ฑ โ†’ ํ…Œ์ŠคํŠธ์˜ ํšจ์šฉ์„ฑ์„ ๋†’์ž„ ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์–ด๋ ค์šธ ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉ

๐Ÿ›  TDD์™€์˜ ๊ด€๊ณ„

ํ…Œ์ŠคํŠธ ์ฃผ๋„ ๊ฐœ๋ฐœ(TDD)์—์„œ๋Š” ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ๊ฐ€ ํ•„์ˆ˜์ ์ธ ์š”์†Œ ์ค‘์˜ ํ•˜๋‚˜ ๋ชจ์˜ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•˜๋ฉด ์ƒ๋‹น ๋ถ€๋ถ„์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉ์ž์˜ ๊ฐœ์ž… ์—†์ด ์ž๋™ํ™” ํ•  ์ˆ˜ ์žˆ์Œ

์‚ฌ์šฉ ์˜ˆ์‹œ

  1. ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค(UI) ํ…Œ์ŠคํŠธ : ์‚ฌ์šฉ์ž์˜ ๋ฐ˜์‘์ด ํ•„์š”ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•  ๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž๊ฐ€ ํ…Œ์ŠคํŠธ์— ์ฐธ์—ฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™ํ™”๋œ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰์ด ์–ด๋ ค์›€. ๋ชจ์˜ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ์‚ฌ์šฉ์ž์˜ ์‘๋‹ต์„ ํ‰๋‚ด๋‚ด์–ด ์‚ฌ์šฉ์ž์˜ ๊ฐœ์ž… ์—†์ด๋„ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰

  2. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(DB) ํ…Œ์ŠคํŠธ : ์ž๋ฃŒ์˜ ๋ณ€๊ฒฝ์„ ์ˆ˜๋ฐ˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์ž‘์—…์„ ํ…Œ์ŠคํŠธ ํ•˜๋Š” ๊ฒฝ์šฐ, ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰ ํ›„ ๋งค๋ฒˆ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ž๋ฃŒ๋ฅผ ์›๋ž˜๋Œ€๋กœ ๋Œ๋ ค๋†”์•ผ ํ•˜๋Š”๋ฐ, ๋ชจ์˜ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์‘๋‹ต์„ ํ‰๋‚ด๋‚ด์–ด ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ ์—†์ด ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ€๋Šฅ

5. Test fixture

Test fixture

์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์ผ๊ด€๋˜๊ฒŒ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ํ™˜๊ฒฝ ํ•œ ๊ณณ์— ๋ชฐ์•„์„œ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธ๋ฆฌํ•จ

์žฅ์ 

  • ๊ฐ ํ…Œ์ŠคํŠธ๊ฐ€ ํ•ญ์ƒ ๋™์ผํ•œ ์„ค์ •์œผ๋กœ ์‹œ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ๋ฅผ ๋ฐ˜๋ณตํ•  ์ˆ˜ ์žˆ์Œ

  • ๋ฉ”์†Œ๋“œ๋ฅผ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ๊ฐ ๊ธฐ๋Šฅ์„ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ

  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์„ค๊ณ„๊ฐ€ ์šฉ์ดํ•จ

  • ์ด์ „ ํ…Œ์ŠคํŠธ ์‹คํ–‰์—์„œ ๋‚จ์€ ํ•ญ๋ชฉ์œผ๋กœ ์ž‘์—…ํ•˜๋Š” ๋Œ€์‹ , ์•Œ๋ ค์ง„ ์ดˆ๊ธฐ ์ƒํƒœ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ๋ฏธ๋ฆฌ ๊ตฌ์„ฑ

ํด๋” ๊ตฌ์กฐ

1. ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

โ”œโ”€โ”€ src
โ”‚   โ”œโ”€โ”€ App.test.tsx
โ”‚   โ”œโ”€โ”€ App.tsx
โ”œโ”€โ”€ fixtures
โ”‚   โ”œโ”€โ”€ index.ts
โ”‚   โ””โ”€โ”€ products.ts
// App.test.ts

import {render, screen} from '@testing-library/react';
import App from './App';
import fixtures from '../fixtures';

jest.mock('./hooks/useFetchProducts', () => () => fixtures.products);

test('App', () => {
    render(<App/>);

    screen.getByText('Apple');
});
// fixtures/products.ts

const products = [
    {
        category: 'Fruits', price: '$1', stocked: true, name: 'Apple',
    },
];

export default products;
// fixtures/index.ts

import products from './products';

export default {
    products,
};

2. mocks ํด๋”๋ฅผ ๋ถ„๋ฆฌํ•  ๊ฒฝ์šฐ

๋ณต์žกํ•ด์ง€๋ฉด ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉ

โ”‚   โ”œโ”€โ”€ hooks
โ”‚   โ”‚   โ”œโ”€โ”€ __mocks__
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ useFetchProducts.ts
โ”‚   โ”‚   โ””โ”€โ”€ useFetchProducts.ts
// App.test.ts

import {render, screen} from '@testing-library/react';
import App from './App';

// Jest.mock('./hooks/useFetchProducts', () => () => fixtures.products);
jest.mock('./hooks/useFetchProducts');

test('App', () => {
    render(<App/>);

    screen.getByText('Apple');
});
// hooks/__mocks__/useFetchProducts.ts

import fixtures from '../../../fixtures';

// Const useFetchProducts = () => fixtures.products; // ์ด๋ ‡๊ฒŒ ์จ๋„ ๋˜์ง€๋งŒ 
const useFetchProducts = jest.fn(() => fixtures.products); // ๋ชจํ‚น์„ ๋“œ๋Ÿฌ๋‚ด๊ธฐ ์œ„ํ•ด ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ๋ฒ•  

export default useFetchProducts;

Last updated