How can I test if a prop is passed to child?

余生长醉 提交于 2020-11-29 23:52:39

问题


My component looks something like this: (It has more functionality as well as columns, but I have not included that to make the example simpler)

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} />
  );
};

Now, I wrote some tests like this:

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(),
  );
});

If you check my component, it has a variable called columns. I am assigning that variable to Table component.

I think, I should test that columns are being passed as props to the Table component. Am I thinking right? If so, can you please tell me how can I write a test case for that?

Also, it will be helpful if you can suggest me how can i test each cell declared inside columns property.


回答1:


It is not recommended to test implementation details, such as component props, with React Testing Library. Instead you should be asserting on the screen content.


Recommended

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

Not Recommended

If you want to test props anyways, you can try the sample code below. Source

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

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

You might consider this approach mainly on the two following scenarios.

You already tried the recommended approach but you noticed the component is:

  1. using legacy code and because of that it makes testing very hard. Refactoring the component would also take too long or be too risky.
  2. is very slow and it drastically increases the testing time. The component is also already tested somewhere else.

have a look at a very similar question here




回答2:


You can use the props() method, doing something like this:

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

Just doing your component.props() then the prop you want, you can make any assert with it.



来源:https://stackoverflow.com/questions/64939196/how-can-i-test-if-a-prop-is-passed-to-child

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!