- Published on
Jest, Enzyme 을 사용한 React 컴포넌트 테스트
Jest, Enzyme 을 사용한 이유
-
Jest (JavaScript unit testing framework. Jest as the test runner, assertion library, and mocking library)
- 간단한 설정
- 스냅샷 테스트
- 변경 사항에 대한 테스트만 재실행하는 Interactive한 감시모드
- 유용한 Fail Message
- Mocks와 Spies
-
Enzyme (JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components’ output)
- Enzyme은 얕은 렌더링, 정적 렌더링 된 마크 업 또는 DOM 렌더링 Method를 지원
- 엘리먼트를 찾고(find), 컴포넌트의 props 등을 읽는 것이 편리함
Setup
- Install Jest
npm install --save-dev jest jest-mock
- Install Enzyme
npm install --save-dev enzyme enzyme-adapter-react-16 enzyme-to-json
- Update package.json
"scripts": {
"test": "jest"
},
"jest": {
"setupFiles": [
"./src/setupTests.js"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
}
- Create a setupTests.js file at ./src/setupTests.js:
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
-
Test 파일 생성
-
Jest는 test코드 파일을 다음위치에서 찾는다.
-
Files with .js suffix in __tests__ folders.
-
Files with .test.js suffix.
-
Files with .spec.js suffix.
-
-
Enzyme을 통한 컴포넌트 렌더링
-
enzyme에는 세 가지 렌더링 Method가 있다.
-
shallow : 간단한 컴포넌트를 메모리 상에 렌더링한다. 단일 컴포넌트를 테스트할 때 유용하다.
-
mount : 자식 컴포넌트를 포함하여 전부 렌더링한다. 다른 컴포넌트와의 관계를 테스트하거나 DOM API 및 React lifecycle method를 사용하는 컴포넌트를 테스트할 때 유용하다.
-
render : 자식 컴포넌트를 포함하여 정적인 html로 렌더링한다. React lifecycle method는 테스트할 수 없다.
-
import { mount } from 'enzyme';
//...
let component = null;
beforeEach(() => {
component = mount(
<SelectDlg
onDlgClose={() => alert('close')}
title={title}
message={message}
onSelect={selectFn}
firstvalue={okValue}
secondvalue={nokValue}
/>
);
});
afterEach(() => {
component.unmount();
});
스냅샷 테스트
-
Jest에서 지원하는 스냅샷 테스트는, 테스트완료시 렌더링결과를 스냅샷을 찍어서 만들어놓고 (__snapshots__ 폴더), 다음 테스트시 렌더링결과를 이전 스냅샷과 비교한다. 렌더링 결과가 달라졌다면, 테스트 실패를 발생시킨다.
-
스냅샷 테스트 실패가 발생하였을 때, 개발자는 현재 결과가 제대로 된것이라면 "u" 키를 눌러서 스냅샷을 현재 결과물로 업데이트 할 수 있다.
it('match snapshot', () => {
expect(component).toMatchSnapshot();
});
Props 테스트
-
Enzyme에서는 컴포넌트 인스턴스에 접근할 수 있다.
-
컴포넌트의 Props를 조회한다.
-
find를 사용하여 DOM Element를 선택할 수 있다.
it('renders title and message', () => {
expect(component.props().title).toBe(title);
expect(component.props().message).toBe(message);
expect(component.find('h2').contains(title)).toBe(true);
expect(component.find('p').text()).toBe(message);
});
이벤트 시뮬레이션 테스트
-
simulate Method를 통해 이벤트를 시뮬레이트 할 수 있다.
-
Jest-mock을 통해 가짜 함수(mock function)를 생성하여 simulate 이벤트 콜백을 테스트한다.
-
mock function은 테스트가 실행되는 동안 가짜함수에 어떤일들이 발생했는지를 기억하기 때문에 가짜함수가 내부적으로 어떻게 사용되는지 검증할 수 있다.
import jest from 'jest-mock';
//...
const okValue = 'ok';
const nokValue = 'nok';
const selectFn = jest.fn();
let component = null;
beforeEach(() => {
component = mount(
<SelectDlg
onDlgClose={() => alert('close')}
title={title}
message={message}
onSelect={selectFn}
firstvalue={okValue}
secondvalue={nokValue}
/>
);
});
//...
it('click select button', () => {
const firstBtn = component.find('button:first-child');
firstBtn.simulate('click');
expect(selectFn).toBeCalledWith(okValue);
});