localStorage 를 적용한 테스트 코드를 작성해보자
Context/ToDoList/index.test.tsx
import React, {useContext} from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import 'jest-styled-components';
import { ToDoListProvider, ToDoListContext } from './index';
beforeEach(() => {
localStorage.clear();
});
describe('ToDoList Context', () => {
it('renders component correctly', () => {
const ChildComponent = () => {
return <div>Child Component</div>;
};
render (
<ToDoListProvider>
<ChildComponent/>
</ToDoListProvider>,
);
const childComponent = screen.getByText('Child Component');
expect(childComponent).toBeInTheDocument();
expect(localStorage.getItem('ToDoList')).toBeNull();
});
it('loads localStorage data and sets it to State', () => {
localStorage.setItem('ToDoList','["ToDo 1","ToDo 2","ToDo 3"]');
const ChildComponent = () => {
const {toDoList} = useContext(ToDoListContext);
return (
<div>
{toDoList.map((toDo) => (
<div key={toDo}>{toDo}</div>
))}
</div>
);
};
render (
<ToDoListProvider>
<ChildComponent/>
</ToDoListProvider>
);
expect(screen.getByText('ToDo 1')).toBeInTheDocument();
expect(screen.getByText('ToDo 2')).toBeInTheDocument();
expect(screen.getByText('ToDo 3')).toBeInTheDocument();
});
it('uses addToDo function', () => {
const ChildComponent = () => {
const { toDoList, addToDo } = useContext(ToDoListContext);
return (
<div>
<div onClick={() => addToDo('study react 1')}>Add ToDo</div>
<div>
{toDoList.map((toDo) => (
<div key={toDo}>{toDo}</div>
))}
</div>
</div>
);
};
render(
<ToDoListProvider>
<ChildComponent/>
</ToDoListProvider>
);
expect(localStorage.getItem('ToDoList')).toBeNull();
const button = screen.getByText('Add ToDo');
fireEvent.click(button);
expect(screen.getByText('study react 1')).toBeInTheDocument();
expect(localStorage.getItem('ToDoList')).toBe('["study react 1"]');
});
it('uses deleteToDo function', () => {
localStorage.setItem('ToDoList', '["ToDo 1", "ToDo 2", "ToDo 3"]');
const ChildComponent = () => {
const { toDoList, deleteToDo } = useContext(ToDoListContext);
return (
<div>
{toDoList.map((toDo, index) => (
<div key={toDo} onClick={() => deleteToDo(index)}>
{toDo}
</div>
))}
</div>
);
};
render(
<ToDoListProvider>
<ChildComponent />
</ToDoListProvider>,
);
const toDoItem = screen.getByText('ToDo 2');
expect(toDoItem).toBeInTheDocument();
fireEvent.click(toDoItem);
expect(toDoItem).not.toBeInTheDocument();
expect(JSON.parse(localStorage.getItem('ToDoList') as string)).not.toContain('ToDo 2');
});
});
Components/InputContainer/index.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import 'jest-styled-components';
import { ToDoListProvider } from 'Contexts';
import { InputContainer } from './index';
describe('<InputContainer />', () => {
it('renders component correctly', () => {
const { container } = render(<InputContainer />);
const input = screen.getByPlaceholderText('할 일을 입력해 주세요');
expect(input).toBeInTheDocument();
const button = screen.getByText('추가');
expect(button).toBeInTheDocument();
//expect(container).toMatchSnapshot();
});
it('empties data after adding data', () => {
render(<InputContainer />);
const input = screen.getByPlaceholderText('할 일을 입력해 주세요') as HTMLInputElement;
const button = screen.getByText('추가');
expect(input.value).toBe('');
fireEvent.change(input, { target: { value: 'study react 1' } });
expect(input.value).toBe('study react 1');
fireEvent.click(button);
expect(input.value).toBe('');
});
it('adds input data to localStorage via Context', () => {
render(
<ToDoListProvider>
<InputContainer />
</ToDoListProvider>,
);
const input = screen.getByPlaceholderText('할 일을 입력해 주세요');
const button = screen.getByText('추가');
expect(localStorage.getItem('ToDoList')).toBeNull();
fireEvent.change(input, { target: { value: 'study react 1' } });
fireEvent.click(button);
expect(localStorage.getItem('ToDoList')).toBe('["study react 1"]');
});
});
Components/ToDoList/index.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import 'jest-styled-components';
import { ToDoListProvider } from 'Contexts';
import { ToDoList } from './index';
describe('<ToDoList />', () => {
it('renders component correctly', () => {
const { container } = render(
<ToDoListProvider>
<ToDoList />
</ToDoListProvider>,
);
const toDoList = screen.getByTestId('toDoList');
expect(toDoList).toBeInTheDocument();
expect(toDoList.firstChild).toBeNull();
//expect(container).toMatchSnapshot();
});
it('shows toDo list', () => {
localStorage.setItem('ToDoList', '["ToDo 1", "ToDo 2", "ToDo 3"]');
render(
<ToDoListProvider>
<ToDoList />
</ToDoListProvider>,
);
expect(screen.getByText('ToDo 1')).toBeInTheDocument();
expect(screen.getByText('ToDo 2')).toBeInTheDocument();
expect(screen.getByText('ToDo 3')).toBeInTheDocument();
expect(screen.getAllByText('삭제').length).toBe(3);
});
it('deletes toDo item', () => {
localStorage.setItem('ToDoList', '["ToDo 1", "ToDo 2", "ToDo 3"]');
render(
<ToDoListProvider>
<ToDoList />
</ToDoListProvider>,
);
const toDoItem = screen.getByText('ToDo 2');
expect(toDoItem).toBeInTheDocument();
fireEvent.click(toDoItem.nextElementSibling as HTMLElement);
expect(toDoItem).not.toBeInTheDocument();
expect(JSON.parse(localStorage.getItem('ToDoList') as string)).not.toContain('ToDo 2');
});
});
App.test.tsx
아래부분만 추가
it('loads localStorage data', () => {
localStorage.setItem('ToDoList', '["ToDo 1", "ToDo 2", "ToDo 3"]');
render(<App />);
expect(screen.getByText('ToDo 1')).toBeInTheDocument();
expect(screen.getByText('ToDo 2')).toBeInTheDocument();
expect(screen.getByText('ToDo 3')).toBeInTheDocument();
expect(screen.getAllByText('삭제').length).toBe(3);
});
결과
npm run test -- --coverage
반응형
'2022 > 리액트+TDD(完)' 카테고리의 다른 글
react-router (0) | 2022.02.12 |
---|---|
Context API / localStorage - 2 (0) | 2022.01.16 |
Context API / localStorage - 1 (0) | 2022.01.14 |
클래스 컴포넌트 라이프 사이클 (0) | 2022.01.13 |
함수 컴포넌트에서 클래스 컴포넌트 변환 (0) | 2022.01.12 |