programing

리액트 테스트 라이브러리를 사용할 때 구성 요소가 올바른 소품으로 렌더링되는지 테스트하는 방법은 무엇입니까?

subpage 2023. 4. 4. 21:18
반응형

리액트 테스트 라이브러리를 사용할 때 구성 요소가 올바른 소품으로 렌더링되는지 테스트하는 방법은 무엇입니까?

이미 단독으로 테스트된 다른 컴포넌트(FetchNextPageButton)를 렌더링하고 있는 컴포넌트가 있습니다.다음 컴포넌트는 다음과 같습니다.

const News = () => (
  <div>
    <h1>News</h1>
    ...
    <FetchNextPageButton query={NEWS_QUERY} path="viewer.news" />
  </div>
)

const Jobs = () => (
  <div>
    <h1>Jobs</h1>
    ...
    <FetchNextPageButton query={JOBS_QUERY} path="viewer.jobs" />
  </div>
)

const Posts = () => (
  <div>
    <h1>Posts</h1>
    ...
    <FetchNextPageButton query={POSTS_QUERY} path="viewer.posts" />
  </div>
)

다른 곳에서 이미 테스트된 기능을 위해 각 컴포넌트에 테스트를 추가할 필요가 없기 때문에 컴포넌트가 렌더링되어 있고 적절한 소품을 전달하고 있는지 테스트하는 것만으로도 충분하다고 생각합니다.

나는 다음과 같은 방법으로 이것을 효소로 쉽게 테스트할 수 있었을 것이다.

expect(wrapper.find('FetchNextPageButton').props()).toMatchObject({
  query: NEWS_QUERY,
  path: "viewer.news"
})

그 대신 React 테스트 라이브러리를 사용하여 테스트하는 가장 좋은 방법이 무엇인지 궁금합니다.

이것이 Kent C의 접근법이다.Dodds(RTL의 창시자)는 그와 상의한 후 나와 공유했다.

import FetchNextPageButton from 'FetchNextPageButton'

jest.mock('FetchNextPageButton', () => {
  return jest.fn(() => null)
})

// ... in your test
expect(FetchNextPageButton).toHaveBeenCalledWith(props, context)

그게 가능하다고 믿지 마세요.RTL은 DOM not React의 컴포넌트 트리에 대한 검증에 주력하는 것처럼 보입니다.

내가 볼 수 있는 유일한 회피책은 조롱하는 것이다.FetchNextPageButton모든 소품을 속성으로 렌더링합니다.

jest.mock("../../../FetchNextPageButton.js", () => 
  (props) => <div data-test-id="FetchNextPageButton" {...props} />);
....
const { getByTestId } = render(<YourComponent />);
expect(getByTestId("FetchNextPageButton")).toHaveAttribute("query", NEWS_QUERY);
expect(getByTestId("FetchNextPageButton")).toHaveAttribute("path", "viewer.news");

물론, 이것은 소품에서의 원시적인 가치만을 위한 것이지만, 사물이나 기능 같은 것을 검증하는 것은 어려울 것입니다.

RTL-Way는 아니지만, 각 컨테이너의 범위를 확인하는 것은 큰 작업이 될 것입니다(그리고 그것을 완전히 무시하는 것은 오히려 위험합니다).

PStoHaveAttribute에서 왔다

제 경우 High Order Component(HOC; 상위 컴포넌트)가 HOC에 전달된 컴포넌트를 올바르게 확장하는지 테스트하고 싶었습니다.

필요한 것은 실제 컴포넌트를 모의로 만들어 HOC에 전달하는 것입니다.기존 답변에서 설명한 것처럼 HOC에 의해 추가된 속성만 예상할 수 있습니다.

// after 'Component' get's passed into withSelectionConstraint, it should have an id prop
const Component = jest.fn(() => <h1>Tag Zam</h1>);
const WithConstraint = withSelectionConstraint(Component, ["instance"], true);
render(<WithConstraint />);

// passing the jest mock to the HOC, enables asserting the actual properties passed by the HOC
expect(Component).toHaveBeenCalledWith(
    expect.objectContaining({ ids: mockInstanceRows.map(x => x.id) }), 
    expect.anything()
)


Ben의 답변을 바탕으로 오류가 발생하지 않는 버전을 작성했습니다.

jest.mock(
  'path/to/your/component',
  () => {
    const MockedComponent = (props: any) => {
      const cleanedProps = Object.keys(props).reduce<Record<string, unknown>>(
        (a, b) => {
          // Needed because html attributes cannot be camel cased
          a[b.toLowerCase()] = props[b].toString();
          return a;
        },
        {}
      );

      return (
        <div data-testid="any-test-id" {...cleanedProps} />
      );
    };

    return MockedComponent;
  }
);

Atribute 값(expect(getByTestId('any-test-id')).toHaveAttribute('attribute','value'))가 문자열화 됩니다.

언급URL : https://stackoverflow.com/questions/58623666/how-to-test-if-a-component-is-rendered-with-the-right-props-when-using-react-tes

반응형