소품이 어린이에게 전달되었는지 어떻게 테스트 할 수 있습니까?

Nov 20 2020

내 구성 요소는 다음과 같습니다. (열뿐만 아니라 더 많은 기능이 있지만 예제를 더 간단하게 만들기 위해 포함하지 않았습니다)

const WeatherReport: FunctionComponent<Props> = ({ cityWeatherCollection, loading, rerender }) => {
  /* some use effects skipped */
  /* some event handlers skipped */

  const columns = React.useMemo(() => [
    {
      header: 'City',
      cell: ({ name, title }: EnhancedCityWeather) => <Link to={`/${name}`} className="city">{title}</Link> }, { header: 'Temp', cell: ({ temperature }: EnhancedCityWeather) => ( <div className="temperature"> <span className="celcius">{`${temperature}°C`}</span>
          <span className="fahrenheit">{` (~${Math.round(temperature * (9 / 5)) + 32}°F)`}</span>
        </div>
      )
    },
    {
      header: '',
      cell: ({ isFavorite } : EnhancedCityWeather) => isFavorite && (
        <HeartIcon
          fill="#6d3fdf"
          height={20}
          width={20}
        />
      ),
    },
  ], []);

  return (
    <Table columns={columns} items={sortedItems} loading={loading} />
  );
};

이제 다음과 같은 테스트를 작성했습니다.

jest.mock('../../../components/Table', () => ({
  __esModule: true,
  default: jest.fn(() => <div data-testid="Table" />),
}));

let cityWeatherCollection: EnhancedCityWeather[];
let loading: boolean;
let rerender: () => {};

beforeEach(() => {
  cityWeatherCollection = [/*...some objects...*/];

  loading = true;
  rerender = jest.fn();

  render(
    <BrowserRouter>
      <WeatherReport
        cityWeatherCollection={cityWeatherCollection}
        loading={loading}
        rerender={rerender}
      />
    </BrowserRouter>
  );
});

it('renders a Table', () => {
  expect(screen.queryByTestId('Table')).toBeInTheDocument();
});

it('passes loading prop to Table', () => {
  expect(Table).toHaveBeenCalledWith(
    expect.objectContaining({ loading }),
    expect.anything(),
  );
});

it('passes items prop to Table after sorting by isFavorite and then alphabetically', () => {
  expect(Table).toHaveBeenCalledWith(
    expect.objectContaining({
      items: cityWeatherCollection.sort((item1, item2) => (
        +item2.isFavorite - +item1.isFavorite
        || item1.name.localeCompare(item2.name)
      )),
    }),
    expect.anything(),
  );
});

내 구성 요소를 확인하면 열이라는 변수가 있습니다. 이 변수를 Table 구성 요소에 할당하고 있습니다.

열이 테이블 구성 요소에 소품으로 전달되고 있는지 테스트해야한다고 생각합니다. 내 생각이 맞아? 그렇다면 테스트 케이스를 작성하는 방법을 알려주시겠습니까?

또한 columns 속성 내에 선언 된 각 셀을 어떻게 테스트 할 수 있는지 제안 해 주시면 도움이 될 것입니다.

답변

1 Doug Nov 21 2020 at 04:41

되는 하지 않는 것이 좋습니다 테스트 라이브러리 반응과 같은 구성 요소 소품 등의 테스트 구현 세부 사항에. 대신 화면 내용에 대해 주장해야합니다.


추천

expect(await screen.findByText('some city')).toBeInTheDocument();
expect(screen.queryByText('filtered out city')).not.toBeInTheDocument();

권장하지 않음

어쨌든 소품을 테스트하고 싶다면 아래 샘플 코드를 시도해 볼 수 있습니다. 출처

import Table from './Table'
jest.mock('./Table', () => jest.fn(() => null))

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

주로 다음 두 가지 시나리오에서이 접근 방식을 고려할 수 있습니다.

이미 권장되는 접근 방식을 시도했지만 구성 요소가 다음과 같습니다.

  1. 레거시 코드를 사용하기 때문에 테스트가 매우 어렵습니다. 구성 요소를 리팩토링하는 것도 시간이 너무 오래 걸리거나 위험합니다.
  2. 매우 느리고 테스트 시간이 크게 늘어납니다. 구성 요소는 이미 다른 곳에서 테스트되었습니다.

여기 에서 매우 유사한 질문을 보십시오

2 OtacílioMaia Nov 21 2020 at 02:45

props()다음과 같이 방법을 사용할 수 있습니다 .

 expect(Table.props().propYouWantToCheck).toBeFalsy();

component.props () 다음 원하는 소품을 수행하면 어떤 주장도 할 수 있습니다.