Enzyme / React 테스트에서 언제 Render and Shallow를 사용해야합니까?


95

이 질문을 게시하기 전에 sqa stackexchange에서 검색을 시도했지만 얕은 및 렌더링에 대한 게시물을 찾지 못 했으므로 누군가가 나를 도울 수 있기를 바랍니다.

반응 구성 요소를 테스트 할 때 얕은 및 렌더링을 언제 사용해야합니까? 에어 비앤비 문서를 기반으로 두 가지의 차이점에 대해 몇 가지 의견을 내놓았습니다.

  1. shallow는 구성 요소 를 하나의 단위로 테스트 하므로 '부모'구성 요소에 사용해야합니다. (예 : 테이블, 래퍼 등)

  2. 렌더는 하위 구성 요소 용입니다.

내가이 질문을 한 이유는 내가 어떤 것을 사용해야하는지 알아내는 데 어려움을 겪고 있기 때문입니다 (문서는 그것들이 매우 유사하다고 말하지만)

그렇다면 특정 시나리오에서 어떤 것을 사용할지 어떻게 알 수 있습니까?


2
shallow ()와 mount ()의 차이점은 shallow ()는 렌더링하는 하위 구성 요소와 분리 된 상태로 구성 요소를 테스트하는 반면 mount ()는 더 깊이 들어가 구성 요소의 하위를 테스트한다는 것입니다. shallow ()의 경우 이는 부모 구성 요소가 렌더링에 실패한 다른 구성 요소를 렌더링하는 경우 부모에 대한 shallow () 렌더링이 여전히 통과 함을 의미합니다.
Shyam Kumar

답변:


160

효소 문서에 따라 :

mount(<Component />) for Full DOM 렌더링은 DOM API와 상호 작용할 수있는 구성 요소가 있거나 구성 요소를 완전히 테스트하기 위해 전체 수명주기가 필요할 수있는 사용 사례에 이상적입니다 (예 : componentDidMount 등).

shallow(<Component />) for Shallow 렌더링은 구성 요소를 하나의 단위로 테스트하도록 제한하고 테스트가 하위 구성 요소의 동작에 대해 간접적으로 주장하지 않도록하는 데 유용합니다.

render반응 컴포넌트를 정적 HTML 로 렌더링 하고 결과 HTML 구조를 분석하는 데 사용됩니다 .

얕은 렌더링에서 여전히 기본 "노드"를 볼 수 있으므로 예를 들어 AVA 를 사양 러너로 사용하여 다음과 같은 (약간 인위적인) 예제를 수행 할 수 있습니다 .

let wrapper = shallow(<TagBox />);

const props = {
    toggleValue: sinon.spy()
};

test('it should render two top level nodes', t => {
    t.is(wrapper.children().length, 2);
});

test('it should safely set all props and still render two nodes', t => {
    wrapper.setProps({...props});
    t.is(wrapper.children().length, 2);
});

test('it should call toggleValue when an x class is clicked', t => {
    wrapper.setProps({...props});
    wrapper.find('.x').last().simulate('click');
    t.true(props.toggleValue.calledWith(3));
});

공지 사항이 렌더링 , 소품을 설정 하고 선택기를 찾는 심지어 합성 이벤트가 모두 얕은 렌더링하여 그냥 사용할 수 있도록 대부분의 시간을 지원합니다.

그러나 구성 요소의 전체 수명주기를 얻을 수 없으므로 componentDidMount에서 일이 발생할 것으로 예상되는 경우 mount(<Component />);

이 테스트는 Sinon 을 사용 하여 구성 요소의componentDidMount

test.only('mount calls componentDidMount', t => {

    class Test extends Component {
        constructor (props) {
            super(props);
        }
        componentDidMount() {
            console.log('componentDidMount!');
        }
        render () {
            return (
                <div />
            );
        }
    };

    const componentDidMount = sinon.spy(Test.prototype, 'componentDidMount');
    const wrapper = mount(<Test />);

    t.true(componentDidMount.calledOnce);

    componentDidMount.restore();
});

위의 내용은 얕은 렌더링 또는 렌더링으로 전달되지 않습니다.

render html 만 제공하므로 다음과 같은 작업을 수행 할 수 있습니다.

test.only('render works', t => {

    // insert Test component here...

    const rendered = render(<Test />);
    const len = rendered.find('div').length;
    t.is(len, 1);
});

도움이 되었기를 바랍니다!


1
나는 여전히 100 %를 얻지 못하는데, 왜 세 동사가 다른 방법을 가져 오는지. 예를 들어 wrapper.getNode ()를 얕게 사용할 수 있지만 렌더링에는 사용할 수 없습니다. 이 통합을 얻는 데 도움이되는 설명 / 링크 / 문서 / 블로그가 있습니까?
Paulquappe

@HenryZhu 문서에서 특정 구성 요소 노드에 대한 DOM 트리를 실제로 모방하려고 시도하기 때문에 렌더링이 얕은 것보다 더 관련이 있음을 문서에서 분명히해야합니다
AGE

11
v3으로 V2에서 효소 마이그레이션뿐만 아니라 얕은 기본적으로에 라이프 사이클 방법을했다 github.com/airbnb/enzyme/blob/master/docs/guides/...
Abhinav 신기


9

shallow ()와 mount ()의 차이점은 shallow ()는 렌더링하는 하위 구성 요소와 분리 된 상태로 구성 요소를 테스트하는 반면 mount ()는 더 깊이 들어가 구성 요소의 하위를 테스트한다는 것입니다.

shallow ()의 경우 이는 부모 구성 요소가 렌더링에 실패한 다른 구성 요소를 렌더링하는 경우 부모에 대한 shallow () 렌더링이 여전히 통과 함을 의미합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.