TodoItem 만들기
이번에는 각 할 일 항목에 대한 정보를 보여주는 TodoItem 컴포넌트를 만들 차례입니다.
아까처럼, 먼저 비어있는 함수형 컴포넌트를 작성해주세요.
TodoItem.js
import React from 'react';
const TodoItem = () => {
return (
<li>
</li>
);
};
export default TodoItem;
이제 테스트 케이스를 작성해봅시다. 이번에 테스트 할 내용은, 해당 컴포넌트에 텍스트와 버튼이 잘 보여지고 있는 지 입니다.
import React from 'react';
import { render, fireEvent } from 'react-testing-library';
import TodoItem from './TodoItem';
describe('TodoItem', () => {
const sampleTodo = {
id: 1,
text: 'TDD 배우기',
done: false
};
it('has text and button', () => {
const { getByText } = render(<TodoItem todo={sampleTodo} />);
getByText('TDD 배우기'); // 텍스트가 잘 보여지는지 확인
getByText('삭제'); // 삭제 버튼이 있는지 확인
});
});
이 테스트 케이스를 통과 시키기 위하여 컴포넌트를 수정해봅시다.
import React from 'react';
const TodoItem = ({ todo }) => {
const { id, text, done } = todo;
return (
<li>
<span>{text}</span>
<button>삭제</button>
</li>
);
};
export default TodoItem;
그 다음에 테스트 할 내용은, done 값이 true 일 때 span 에 취소선이 그어지는 지 입니다.
TodoItem.test.js
import React from 'react';
import { render, fireEvent } from 'react-testing-library';
import TodoItem from './TodoItem';
describe('TodoItem', () => {
const sampleTodo = {
id: 1,
text: 'TDD 배우기',
done: false
};
it('has text and button', () => {
const { getByText } = render(<TodoItem todo={sampleTodo} />);
getByText('TDD 배우기'); // 텍스트가 잘 보여지는지 확인
getByText('삭제'); // 삭제 버튼이 있는지 확인
});
it('gives line-through style to span', () => {
// span 에 text-decoration: line-through 속성을 주는지 확인
const { getByText } = render(
<TodoItem todo={{ ...sampleTodo, done: true }} />
);
const span = getByText('TDD 배우기'); // 텍스트가 잘 보여지는지 확인
expect(span.style.textDecoration).toBe('line-through'); // 스타일 확인
});
});
이제 위 테스트 케이스를 통과시켜줍시다!
TodoItem.js
import React from 'react';
const TodoItem = ({ todo }) => {
const { id, text, done } = todo;
return (
<li>
<span
style={{
textDecoration: done ? 'line-through' : 'none'
}}
>
{text}
</span>
<button>삭제</button>
</li>
);
};
export default TodoItem;
꽤 간단하지요?
이번에는 TodoItem 에 onToggle 과 onRemove 라는 props 를 넣어주었을 때, span 을 클릭하면 onToggle 을 호출하고 button 을 클릭하면 onRemove 가 호출되는 기능을 테스트해보겠습니다. 해당 함수들에는 파라미터로 id 값을 넣어주어야 합니다.
TodoItem.test.js
import React from 'react';
import { render, fireEvent } from 'react-testing-library';
import TodoItem from './TodoItem';
describe('TodoItem', () => {
const sampleTodo = {
id: 1,
text: 'TDD 배우기',
done: false
};
it('has text and button', () => {
const { getByText } = render(<TodoItem todo={sampleTodo} />);
getByText('TDD 배우기'); // 텍스트가 잘 보여지는지 확인
getByText('삭제'); // 삭제 버튼이 있는지 확인
});
it('gives line-through style to span', () => {
// span 에 text-decoration: line-through 속성을 주는지 확인
const { getByText } = render(
<TodoItem todo={{ ...sampleTodo, done: true }} />
);
const span = getByText('TDD 배우기'); // 텍스트가 잘 보여지는지 확인
expect(span.style.textDecoration).toBe('line-through'); // 스타일 확인
});
it('calls onToggle and onRemove', () => {
const onToggle = jest.fn();
const onRemove = jest.fn();
const { getByText } = render(
<TodoItem todo={sampleTodo} onToggle={onToggle} onRemove={onRemove} />
);
const span = getByText('TDD 배우기');
const button = getByText('삭제');
fireEvent.click(span); // span 클릭
expect(onToggle).toBeCalledWith(1); // 파라미터 1 (id) 로 호출했는지 확인
fireEvent.click(button); // button 클릭
expect(onRemove).toBeCalledWith(1); // 파라미터 1 (id) 로 호출했는지 확인
});
});
이제 TodoItem 컴포넌트에서 onToggle 과 onRemove props 를 사용하여 위 테스트 케이스를 통과시켜봅시다.
import React from 'react';
const TodoItem = ({ todo, onToggle, onRemove }) => {
const { id, text, done } = todo;
return (
<li>
<span
style={{
textDecoration: done ? 'line-through' : 'none'
}}
onClick={() => onToggle(id)}
>
{text}
</span>
<button onClick={() => onRemove(id)}>삭제</button>
</li>
);
};
export default TodoItem;
테스트 케이스가 모두 통과했나요? 이제 다음 컴포넌트를 만들어봅시다.