SoYoung210 / soso-tip

🍯소소한 팁들과 정리, 버그 해결기를 모아두는 레포
24 stars 0 forks source link

Storybook shoryshots + Recharts(option: IntersectionObserver) Error #43

Open SoYoung210 opened 4 years ago

SoYoung210 commented 4 years ago

Desc

recharts 의 ResponsiveContainer를 사용하는 경우 스토리북 스냅샷 테스트에서 아래와 같은 에러 발생

TypeError: Cannot read property 'parentElement' of null

at ResizeDetector.componentWillUnmount (node_modules/react-resize-detector/lib/components/ResizeDetector.js:105:105)
at callComponentWillUnmountWithTimer (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:10194:12)

Why?

(추측) ResponsiveContainer내부적으로 Class Component사용해서 Jest환경에서 잘 돌지 않는 것으로 추정.

Solution

createNodeMock생성

function createNodeMock() {
  const doc = document.implementation.createHTMLDocument();
  return { parentElement: doc.body };
}

ResponsiveContainer에 대해, createNodeMock사용하도록 설정

import initStoryshots, { snapshotWithOptions } from '@storybook/addon-storyshots';

initStoryshots({
  test: snapshotWithOptions(story =>({
    createNodeMock: (element) => {

      if (element.type === ResponsiveContainer) {
        return createNodeMock()
      }
      return element
    },
  })),
});

만약 IntersectionObserver를 사용한다면?

위와 같이 적용할경우 target must be an Element에러가 발생할 수 있음.

at IntersectionObserver.observe (node_modules/intersection-observer/intersection-observer.js:217:11)
at src/bpl/Graph/useIntersectionObserver.ts:33:16

IntersectionObserver객체를 mocking해주어야 함.

initStoryshots({
  test: snapshotWithOptions(story =>({
    createNodeMock: (element) => {
      beforeEach(() => {
        // IntersectionObserver isn't available in test environment
        const mockIntersectionObserver = jest.fn();
        mockIntersectionObserver.mockReturnValue({
          observe: () => null,
          unobserve: () => null,
          disconnect: () => null
        });
        window.IntersectionObserver = mockIntersectionObserver;
      });

      if (element.type === ResponsiveContainer) {
        return createNodeMock()
      }
      return element
    },
  })),
});

Ref