반응형

Enzyme 테스트 환경 설정

library 설치

yarn add --dev enzyme enzyme-adapter-react-16 enzyme-to-json

setupTests.js 파일 생성

  • 경로 : <프로젝트>/src/setupTests.js
import { configure, mount, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

global.mount = mount;
global.shallow = shallow;

package.json 설정 수정

{
    ...
    "jest": {
        ...
        "setupFilesAfterEnv": [
            "<rootDir>/src/setupTests.js"
        ],
        ...
        // alias로 경로를 지정해 사용할 경우 아래같은 설정이 없으면 오류 발생        
        "moduleNameMapper": {
            "@components/(.*)": "<rootDir>/src/components/$1"
        },
        ...
        // snapshot 처리시 필요한 모듈 지정
        "snapshotSerializers": ["enzyme-to-json/serializer"],
        ...
    }
    ...
}

테스트 코드 작성

// index.js

import React from 'react';

const TestComponent = () => {
    return <div>Hi</div>;
};

export default TestComponent;
// index.test.js

import React from 'react';
import TestComponent from '@components/TestComponent';

describe('<TestComponent />', () => {
    it('matches snapshot', () => {
        const wrapper = mount(<TestComponent />);
        expect(wrapper).toMatchSnapshot();
    });
});

테스트 실행

yarn test

테스트 코드 예제

Snapshot 테스트

// index.js

import React from 'react';

const TestComponent = () => {
    return <div>Hi</div>;
};

export default TestComponent;
// index.test.js

import React from 'react';
import TestComponent from '@components/TestComponent';

describe('<TestComponent />', () => {
    // 최초 테스트 실행시 스냅샷 파일을 만들고
    // 두 번째 테스트 실행시부터 생성된 스냅샷과 비교하여 일치하는지 테스트
    // 스냅샷은 상대경로에 index.test.js.snap 파일로 저장됨
    it('matches snapshot', () => {
        // mount : TestComponent 하위에 리액트 컴포넌트가 포함되어있으면 해당 컴포넌트도 html 태그로 변환된 값을 반환
        const wrapper = mount(<TestComponent />);
        
        // shallow : TestComponent 하위에 리액트 컴포넌트가 포함되어 있으면 해당 컴포넌트는 html 태그로 변환하지 않은 값을 반환
        // const wrapper = shallow(<TestComponent />);
        
        expect(wrapper).toMatchSnapshot();
    });
});

state, props 테스트

  • index.js
import React, { Component } from 'react';

class Counter extends Component {
    constructor(props) {
        super(props);

        this.state = {
            count: props.count
        };
    }

    handleClickPlus = () => {
        this.setState({
            count: this.state.count + 1
        });
    };

    render() {
        return (
            <div>
                count : {this.state.count}
                <button id={'plus-button'} onClick={this.handleClickPlus}>
                    +
                </button>
            </div>
        );
    }
}

export default Counter;
  • index.test.js
import React from 'react';
import { mount } from 'enzyme';
import Counter from '@components/Counter';

describe('<Counter />', () => {
    it('state 테스트', () => {
        const wrapper = mount(<Counter count={1} />);
        const plusButton = wrapper.find('#plus-button');

        expect(wrapper.state().count).toBe(1);

        plusButton.simulate('click');

        expect(wrapper.state().count).toBe(2);
    });

    it('props 테스트', () => {
        const wrapper = mount(<Counter count={1} />);

        expect(wrapper.props().count).toBe(1);
    });
});

DOM 테스트

// index.js

import React from 'react';

const TestComponent = ({ message }) => {
    return <div id={'message'}>{message}</div>;
};

export default TestComponent;
index.test.js

import React from 'react';
import TestComponent from '@components/TestComponent';

describe('<TestComponent />', () => {
    it('DOM 테스트', () => {
        const wrapper = mount(<TestComponent message={'Hello World 123'} />);
        const messageElement = wrapper.find('div#message');

        expect(messageElement.contains('Hello World 123')).toBe(true);
        expect(messageElement.text()).toBe('Hello World 123');
    });
});

Event Trigger 테스트

// index.js

import React, { useState } from 'react';

const Counter = () => {
    const [number, setNumber] = useState(0);

    return (
        <div>
            <h2>{number}</h2>
            <button onClick={() => setNumber(number + 1)}>+1</button>
            <button onClick={() => setNumber(number - 1)}>-1</button>
        </div>
    );
};

export default Counter;
// index.test.js

import React from 'react';
import Counter from '@components/Counter';

describe('<Counter />', () => {
    it('Event Trigger 테스트', () => {
        const wrapper = mount(<Counter />);
        const number = wrapper.find('h2');
        const plusButton = wrapper.findWhere(
            node => node.type() === 'button' && node.text() === '+1'
        );

        plusButton.simulate('click');
        plusButton.simulate('click');

        expect(number.text()).toBe('2');
    });   
});

참고

반응형

'Development > React' 카테고리의 다른 글

[React] Library  (0) 2020.12.30
[React] react-testing-library  (0) 2019.12.29
[React] Setting  (0) 2019.09.08
[React] ETC  (0) 2019.08.29
[React] setupProxy  (0) 2019.05.29

+ Recent posts