IT/기초 지식

[Enzyme] shallow와 instance의 차이점

개발자 두더지 2023. 3. 13. 20:48
728x90

Enzyme이란?


 Airbnb사가 제공하고 있는 React의 컴포넌트 테스트 툴이다. 컴포넌트를 shallow(얕은 복사), mount(깊은 복사)하여 무언가를 파괴시키지 않고 UI를 테스트할 수 있다.

그 중에서도 shallow와 instance의 차이에 대해 잘 몰랐었기에 이번 기회에 정리해보고자 한다.

 

 

shallow는?


Enzyme에는 세 가지 렌더링 방법이 있다. 

  • Shallow Rendering
  • Full DOM Rendering
  • Static Rendering

 세 가지의 차이점은 설명이 길어지므로 공식 사이트를 참조하길 바란다. 

 shallow Rendering는 이 세 가지 방법 중에 하나로, 얕다는 의미 그대로 먼저 이해해두면 좋을 것 같다. 이번 포스팅을 통해서 shallow Rendering의 shallow()와 instance()의 차이점에 대해서 알아보고자한다.

 

 

shallow()의 사용법


describe('<MyComponent/>의 테스트입니다.', () => {
  it('shallow()를 사용해 보자.', () => {
    const wrapper = shallow(<MyComponent />);
    expect(wrapper.find(Foo)).to.have.length(3);
  });
});

 다음과 같은 형식으로 사용한다. shallow()를 사용하여 ShallowWrapper를 만들 수 있고 이에 대해 find(), html()등의 메소드를 사용하여 다양한 테스트를 할 수 있다.

  참고로 find(), html()과 같은 메소드에 대한 설명은 여기를 참고하길 바란다.

 

 

instance()는?


describe('shallow의 테스트입니다.', () => {
  it('instance()를 사용해보자.', () => {
    const wrapper = shallow(<MyComponent />);
    const inst = wrapper.instance();
    expect(inst).to.be.instanceOf(MyComponent);
  });
});

 실제 코드를 먼저 보자. shallow()를 사용한 후에 wrapper에 대해 instance()를 사용하고 있다. instance()는 문자 그대로 인스턴스(실체)를 작성하는 메소드이다.

 정확히 말하자면 ReactComponent를 반환하는 메소드이다. 여기서 의문이 생길 것이다. ShallowWrapper과 무엇이 다른가라는 의문말이다.  ShallowWrapper도 인스턴스같은 분위기를 풍기지만 그렇지 않다. 지금부터 본격적으로 그 차이에 대해 알아보자.

 

 

ShallowWrapper과 instance의 차이점


 shallow()로 만든 ShallowWrapper에 대해서는 Enzyme에서 제공하는 모든 메소드를 사용할 수 있다. 그에 반해 instance()를 이용하여 작성한 인스턴스는 Enzyme가 제공하고 있는 메소드를 사용할 수 없다. 컴포넌트에 작성한 메소드만을 사용할 수 있다.

 아래 구체적인 예를 확인해보자. 예를 들어 아래와 같은 클래스가 있다고 가정하자.

class Human extends React.Component {
  handleClick = () {
    console.log("클릭 됐습니다.");
  };

  render() {
    return (
      <div>안녕하세요.</div>
    );
  }
}

 이 클래스를 테스트할 때에 테스트 스크립트에서 shallow() 사용한 경우, 다음과 같은 Enzyme가 제공하고 있는 find() 메소드를 사용할 수 있다.

describe('<Human/>를 테스트합니다.', () => {
  it('shallow()만을 사용해보자.', () => {
    const wrapper = shallow(<Human />);
    wrapper.find('div');
  });
});

 이번에는 instance()를 사용한 코드를 살펴보자.

describe('<Human/>를 테스트합니다.', () => {
  it('instance()를 사용해보자.', () => {
    const wrapper = shallow(<Human />);
    const instance = wrapper.instance()
    wrapper.find('div');    // OK
    instance.find('div');   // find()는 Human클래스에 없으므로 에러가 발생한다.
    instance.handleClick(); // Human클래스에 handleClick()가 있으므로, OK
  });
});

 즉, 정리하자면 instance()를 사용하여 생성한 ReactComponent의 경우 클래스에 적혀있는 메소드만 쓸 수 있다라는 차이가 있다고 할 수 있다.


참고자료

https://qiita.com/kotaonaga/items/d71c2912d6ddc60651db

https://qiita.com/ckoshien/items/6d7801d0e7d0d8329bc9

728x90