Jest와 Enzyme을 사용하여 함수형 컴포넌트에서 함수를 Mock하는 방법

Jest/Enzyme: 함수형 컴포넌트에서의 Mock 함수 리액트에서 함수형 컴포넌트를 작업할 때, Mock 함수를 사용하는 컴포넌트를 테스트해야하는 상황에 처할 수 있습니다. 그 중 하나는 버튼이 있는 함수형 컴포넌트에서 별도의 함수를 호출하는 onClick 핸들러가 있는 경우로, 테스트 중에 …

title_thumbnail(Jest와 Enzyme을 사용하여 함수형 컴포넌트에서 함수를 Mock하는 방법)

Jest/Enzyme: 함수형 컴포넌트에서의 Mock 함수

리액트에서 함수형 컴포넌트를 작업할 때, Mock 함수를 사용하는 컴포넌트를 테스트해야하는 상황에 처할 수 있습니다. 그 중 하나는 버튼이 있는 함수형 컴포넌트에서 별도의 함수를 호출하는 onClick 핸들러가 있는 경우로, 테스트 중에 해당 함수가 올바르게 호출되는지 확인하고 싶을 때입니다.

간단한 예제

이 개념을 이해하기 위해 간단한 예제를 살펴보겠습니다:

const remove = () => {
  // ... 어떤 작업 수행
}

const RemoveButton = (props) => (
  <Button onClick={() => remove()}>
    Remove
  </Button>
);

이 예제에서는 RemoveButton이라는 함수형 컴포넌트가 버튼을 렌더링합니다. 버튼 클릭 시 remove 함수가 호출됩니다.

remove 함수 모킹하기

이제 테스트 중에 remove 함수를 모킹하는 방법에 대해 알아보겠습니다. 다음 방법을 시도해 볼 수 있었을 것입니다:

it('클릭 시 remove 함수를 호출해야 함', () => {
  const test = shallow(<RemoveButton />);
  const mockFunction = jest.fn();
  test.instance().remove = mockFunction;
  test.find('Button').simulate('click');
  expect(mockFunction).toHaveBeenCalled();
});

그러나 remove 함수가 스코프 밖에 있기 때문에 .instance().remove 방법이 예상대로 작동하지 않는 것을 알 수 있었을 것입니다.

작동하는 솔루션

remove 함수를 성공적으로 모킹할 수 있는 대안적인 방법을 살펴보겠습니다:

// ---- comp.js ----
import * as React from 'react';
import * as comp from './comp';

export const remove = () => {
  // ... 어떤 작업 수행
}

export const RemoveButton = (props) => (
  <div onClick={() => comp.remove()}>
    Remove
  </div>
);


// ---- comp.test.js ----
import * as React from 'react';
import { shallow } from 'enzyme';

import * as comp from './comp';

describe('RemoveButton', () => {
  it('클릭 시 remove 함수를 호출해야 함', () => {
    const mock = jest.spyOn(comp, 'remove');
    mock.mockImplementation(() => {});
    const component = shallow(<comp.RemoveButton />);
    component.find('div').simulate('click');
    expect(mock).toHaveBeenCalled();
    mock.mockRestore();
  });
});

comp.js 모듈에서 remove 함수를 내보내고, 이를 가져와 RemoveButton 컴포넌트 내에서 사용함으로써 테스트 중에 함수를 효과적으로 모킹할 수 있습니다.

remove를 Prop으로 전달하기

위의 솔루션은 작동하지만, remove 함수를 RemoveButton 컴포넌트에 prop으로 전달하는 것이 더 좋은 방법입니다. 이 방법은 코드를 더 깔끔하고 재사용 가능하게 만듭니다:

const RemoveButton = (props) => (
  <Button onClick={() => props.remove()}>
    Remove
  </Button>
)

// 테스트 파일
it('클릭 시 remove 함수를 호출해야 함', () => {
  const mockFunction = jest.fn();
  const test = shallow(<RemoveButton remove={mockFunction} />);
  test.find('Button').simulate('click');
  expect(mockFunction).toHaveBeenCalled();
});

remove 함수를 prop으로 전달하면 컴포넌트의 테스트성과 재사용성이 향상됩니다.

결론

이 블로그 포스트에서는 Jest와 Enzyme을 사용하여 함수형 컴포넌트에서 함수를 모킹하는 방법에 대해 논의했습니다. 두 가지 방법인 instance 접근 방식과 함수를 prop으로 전달하는 방법을 살펴보았습니다. 첫 번째 방법이 동작할 수 있지만, 두 번째 접근 방식이 더 깨끗하고 강력하게 권장됩니다. 함수를 prop으로 전달함으로써 컴포넌트는 더 테스트 가능하고 재사용 가능해집니다.

이제 함수를 함수형 컴포넌트에서 정확하게 모킹하고 React 애플리케이션에 대한 효과적인 테스트를 작성하는 방법에 대해 이해하셨을 것입니다.

참고 자료 : 

reactjs

Leave a Comment