πŸ‘©β€πŸ’»
Megaptera Frontend
  • 주차별 ν•™μŠ΅
    • megaptera-front
    • 1. 개발 ν™˜κ²½
      • 1. 개발 ν™˜κ²½
      • 2. TypeScript
      • 3. React
      • 4. Testing Library
      • 5. Parcel & ESLint
      • ν•œ μ£Όλ₯Ό 마치며
    • 2. JSX
      • 1. JSX
      • ν•œ μ£Όλ₯Ό 마치며
    • 3. React둜 μ‚¬κ³ ν•˜κΈ°
      • 1. React Component
      • 2. React State
      • ν•œ μ£Όλ₯Ό 마치며
    • 4. React Hooks
      • 1. Express
      • 2. Fetch API & CORS
      • 3. React의 Hook
      • 4. useRef & Custom Hook
      • 5. usehooks-ts
      • ν•œ μ£Όλ₯Ό 마치며
    • 5. ν…ŒμŠ€νŠΈ
      • 1. TDD
      • 2. React Testing Library
      • 3. MSW
      • 4. Playwright
      • ν•œ μ£Όλ₯Ό 마치며
    • 6. External Store
      • 1. External Store
      • 2. TSyringe
      • 3. Redux λ”°λΌν•˜κΈ°
      • 4. usestore-ts
      • ν•œ μ£Όλ₯Ό 마치며
    • 7. React Router
      • 1. Routing
      • 2. Routes
      • 3. Router
      • 4. Navigation
      • ν•œ μ£Όλ₯Ό 마치며
    • 8. CSS in JS
      • 1. Design System
      • 2. Style Basics
      • 3. CSS in JS
      • 4. styled-components
      • 5. props와 attrs
      • 6. Global Style & Theme
      • ν•œ μ£Όλ₯Ό 마치며
    • 9. μ‡Όν•‘λͺ° λͺ©λ‘, μƒν’ˆ νŽ˜μ΄μ§€
      • 1. κ°œλ°œν•˜κΈ° μ „ μ€€λΉ„
      • 2. λͺ©λ‘ 보기
      • 3. μƒν’ˆ 상세 보기
      • 4. μž₯λ°”κ΅¬λ‹ˆ 보기
      • 5. μž₯λ°”κ΅¬λ‹ˆμ— μƒν’ˆ λ‹΄κΈ°
      • ν•œ μ£Όλ₯Ό 마치며
    • 10. μ‚¬μš©μž 인증, 인가
      • 1. 둜그인
      • 2. λ‘œκ·Έμ•„μ›ƒ
      • 3. νšŒμ›κ°€μž…
      • 4. μ£Όλ¬Έ λͺ©λ‘ & μ£Όλ¬Έ 상세
      • ν•œ μ£Όλ₯Ό 마치며
    • 11. μ£Όλ¬Έ, 결제
      • 1. 배솑 정보 μž…λ ₯
      • 2. ν¬νŠΈμ› 결제 μš”μ²­
      • 3. 배솑 및 결제 정보 전달
      • ν•œ μ£Όλ₯Ό 마치며
    • 12. μ–΄λ“œλ―Ό
      • 1. κ΄€λ¦¬μž μ›Ή μ‚¬μ΄νŠΈ 개발 μ‹œμž‘
      • 2. 둜그인, μ‚¬μš©μž λͺ©λ‘
      • 3. μΉ΄ν…Œκ³ λ¦¬ 관리
      • 4. μ£Όλ¬Έ 관리
      • 5. μƒν’ˆ 관리
      • ν•œ μ£Όλ₯Ό 마치며
Powered by GitBook
On this page
  • 1. React Testing Library
  • μž₯점
  • 2. given - when - then νŒ¨ν„΄
  • 3. ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„±ν•˜κΈ°
  • 주의점
  • μ»΄ν¬λ„ŒνŠΈμ˜ μΈν„°νŽ˜μ΄μŠ€ 점검
  • BDD μŠ€νƒ€μΌλ‘œ μ½”λ“œ μˆ˜μ •, μž…λ ₯ κΈ°λŠ₯ ν…ŒμŠ€νŠΈ
  • API μš”μ²­ μ½”λ“œ λͺ¨ν‚Ή
  • 4. Mocking
  • μ‚¬μš© μ˜ˆμ‹œ
  • 5. Test fixture
  • μž₯점
  • 폴더 ꡬ쑰
  1. 주차별 ν•™μŠ΅
  2. 5. ν…ŒμŠ€νŠΈ

2. React Testing Library

Previous1. TDDNext3. MSW

Last updated 2 years ago

1. React Testing Library

πŸ’‘ React μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚¬μš©μž μž…μž₯에 κ°€κΉκ²Œ ν…ŒμŠ€νŠΈν•  수 μžˆλŠ” 도ꡬ UI ν…ŒμŠ€νŠΈμ— νŠΉν™”λœ 라이브러리 E2E Test처럼 μ‚¬μš© κ°€λŠ₯ β†’ λΈŒλΌμš°μ €μ—μ„œ μ‚¬μš©μžκ°€ μ‹€μ œλ‘œ μ‚¬μš©ν•˜λ“―μ΄ ν…ŒμŠ€νŠΈ

πŸ›  기쑴의 도ꡬ

μ‚¬μš©μž μž…μž₯μ—μ„œ λ³΄λ‹€λŠ” ν•΄ν‚Ήν•˜λŠ” λŠλ‚ŒμœΌλ‘œ μ‚¬μš©ν•˜λ„λ‘ λ˜μ–΄ μžˆμ—ˆμŒ 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

μ†Œν”„νŠΈμ›¨μ–΄λ₯Ό μΌκ΄€λ˜κ²Œ ν…ŒμŠ€νŠΈν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ” ν™˜κ²½ ν•œ 곳에 λͺ°μ•„μ„œ λ‹€λ₯Έ κ³³μ—μ„œ μ‚¬μš©ν•˜κΈ° νŽΈλ¦¬ν•¨

μž₯점

  • 각 ν…ŒμŠ€νŠΈκ°€ 항상 λ™μΌν•œ μ„€μ •μœΌλ‘œ μ‹œμž‘ν•˜κΈ° λ•Œλ¬Έμ— ν…ŒμŠ€νŠΈλ₯Ό λ°˜λ³΅ν•  수 있음

  • λ©”μ†Œλ“œλ₯Ό λ‹€λ₯Έ ν•¨μˆ˜λ‘œ λΆ„λ¦¬ν•˜κ³  각 κΈ°λŠ₯을 λ‹€λ₯Έ ν…ŒμŠ€νŠΈμ— μž¬μ‚¬μš©ν•  수 있음

  • ν…ŒμŠ€νŠΈ μ½”λ“œ 섀계가 μš©μ΄ν•¨

  • 이전 ν…ŒμŠ€νŠΈ μ‹€ν–‰μ—μ„œ 남은 ν•­λͺ©μœΌλ‘œ μž‘μ—…ν•˜λŠ” λŒ€μ‹ , μ•Œλ €μ§„ 초기 μƒνƒœλ‘œ ν…ŒμŠ€νŠΈλ₯Ό 미리 ꡬ성

폴더 ꡬ쑰

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;

React Testing Library κΉƒν—ˆλΈŒ
React Testing Library 곡식 λ¬Έμ„œ
jest-dom
enzyme
πŸ”— μ‹€μŠ΅ 링크
πŸ”— μ‹€μŠ΅ 링크
λͺ¨μ˜ 객체
Test fixture