如何测试 prop 是否传递给 child?

Vis*_*hal 8 typescript reactjs jestjs react-testing-library

我的组件看起来像这样:(它具有更多功能和列,但我没有包含它以使示例更简单)

\n
const WeatherReport: FunctionComponent<Props> = ({ cityWeatherCollection, loading, rerender }) => {\n  /* some use effects skipped */\n  /* some event handlers skipped */\n\n  const columns = React.useMemo(() => [\n    {\n      header: 'City',\n      cell: ({ name, title }: EnhancedCityWeather) => <Link to={`/${name}`} className="city">{title}</Link>\n    },\n    {\n      header: 'Temp',\n      cell: ({ temperature }: EnhancedCityWeather) => (\n        <div className="temperature">\n          <span className="celcius">{`${temperature}\xc2\xb0C`}</span>\n          <span className="fahrenheit">{` (~${Math.round(temperature * (9 / 5)) + 32}\xc2\xb0F)`}</span>\n        </div>\n      )\n    },\n    {\n      header: '',\n      cell: ({ isFavorite } : EnhancedCityWeather) => isFavorite && (\n        <HeartIcon\n          fill="#6d3fdf"\n          height={20}\n          width={20}\n        />\n      ),\n    },\n  ], []);\n\n  return (\n    <Table columns={columns} items={sortedItems} loading={loading} />\n  );\n};\n
Run Code Online (Sandbox Code Playgroud)\n

现在,我写了一些这样的测试:

\n
jest.mock('../../../components/Table', () => ({\n  __esModule: true,\n  default: jest.fn(() => <div data-testid="Table" />),\n}));\n\nlet cityWeatherCollection: EnhancedCityWeather[];\nlet loading: boolean;\nlet rerender: () => {};\n\nbeforeEach(() => {\n  cityWeatherCollection = [/*...some objects...*/];\n\n  loading = true;\n  rerender = jest.fn();\n\n  render(\n    <BrowserRouter>\n      <WeatherReport\n        cityWeatherCollection={cityWeatherCollection}\n        loading={loading}\n        rerender={rerender}\n      />\n    </BrowserRouter>\n  );\n});\n\nit('renders a Table', () => {\n  expect(screen.queryByTestId('Table')).toBeInTheDocument();\n});\n\nit('passes loading prop to Table', () => {\n  expect(Table).toHaveBeenCalledWith(\n    expect.objectContaining({ loading }),\n    expect.anything(),\n  );\n});\n\nit('passes items prop to Table after sorting by isFavorite and then alphabetically', () => {\n  expect(Table).toHaveBeenCalledWith(\n    expect.objectContaining({\n      items: cityWeatherCollection.sort((item1, item2) => (\n        +item2.isFavorite - +item1.isFavorite\n        || item1.name.localeCompare(item2.name)\n      )),\n    }),\n    expect.anything(),\n  );\n});\n
Run Code Online (Sandbox Code Playgroud)\n

如果您检查我的组件,它有一个名为 columns 的变量。我将该变量分配给表组件。

\n

我认为,我应该测试列是否作为道具传递给 Table 组件。我想得对吗?如果是这样,您能告诉我如何为此编写测试用例吗?

\n

另外,如果您能建议我如何测试 columns 属性中声明的每个单元格,这也会很有帮助。

\n

Dou*_*oug 11

建议使用 React 测试库来测试实现细节,例如组件 props。相反,您应该在屏幕内容上断言。


受到推崇的

expect(await screen.findByText('some city')).toBeInTheDocument();
expect(screen.queryByText('filtered out city')).not.toBeInTheDocument();
Run Code Online (Sandbox Code Playgroud)

不建议

如果你想测试 props,你可以尝试下面的示例代码。来源

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

// ... in your test
expect(Table).toHaveBeenCalledWith(props, context)
Run Code Online (Sandbox Code Playgroud)

您可能主要在以下两种情况下考虑此方法。

您已经尝试过推荐的方法,但您注意到该组件是:

  1. 使用遗留代码,因此使得测试变得非常困难。重构组件也会花费太长时间或风险太大。
  2. 非常慢并且大大增加了测试时间。该组件也已经在其他地方进行了测试。

看看这里一个非常相似的问题