我如何测试道具是否传递给 child?
How can I test if a prop is passed to child?
我的组件看起来像这样:(它有更多的功能和列,但我没有包含它以使示例更简单)
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 组件。
我认为,我应该测试列是否作为 props 传递给 Table 组件。我的想法对吗?如果是这样,您能告诉我如何为此编写测试用例吗?
此外,如果您能建议我如何测试在列 属性.
内声明的每个单元格,这将很有帮助
您可以使用 props()
方法,执行如下操作:
expect(Table.props().propYouWantToCheck).toBeFalsy();
只要做你的 component.props() 然后你想要的道具,你可以用它做任何断言。
not recommended 使用 React 测试库测试实现细节,例如组件 props。相反,您应该在屏幕内容上断言。
推荐
expect(await screen.findByText('some city')).toBeInTheDocument();
expect(screen.queryByText('filtered out city')).not.toBeInTheDocument();
不推荐
如果你想测试道具,你可以试试下面的示例代码。 Source
import Table from './Table'
jest.mock('./Table', () => jest.fn(() => null))
// ... in your test
expect(Table).toHaveBeenCalledWith(props, context)
您可能主要在以下两种情况下考虑这种方法。
您已经尝试过推荐的方法,但您注意到组件是:
- 使用遗留代码,因此使测试变得非常困难。重构组件也会花费太长时间或风险太大。
- 非常慢,并且大大增加了测试时间。该组件也已经在其他地方进行了测试。
看看一个非常相似的问题
我的组件看起来像这样:(它有更多的功能和列,但我没有包含它以使示例更简单)
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 组件。
我认为,我应该测试列是否作为 props 传递给 Table 组件。我的想法对吗?如果是这样,您能告诉我如何为此编写测试用例吗?
此外,如果您能建议我如何测试在列 属性.
内声明的每个单元格,这将很有帮助您可以使用 props()
方法,执行如下操作:
expect(Table.props().propYouWantToCheck).toBeFalsy();
只要做你的 component.props() 然后你想要的道具,你可以用它做任何断言。
not recommended 使用 React 测试库测试实现细节,例如组件 props。相反,您应该在屏幕内容上断言。
推荐
expect(await screen.findByText('some city')).toBeInTheDocument();
expect(screen.queryByText('filtered out city')).not.toBeInTheDocument();
不推荐
如果你想测试道具,你可以试试下面的示例代码。 Source
import Table from './Table'
jest.mock('./Table', () => jest.fn(() => null))
// ... in your test
expect(Table).toHaveBeenCalledWith(props, context)
您可能主要在以下两种情况下考虑这种方法。
您已经尝试过推荐的方法,但您注意到组件是:
- 使用遗留代码,因此使测试变得非常困难。重构组件也会花费太长时间或风险太大。
- 非常慢,并且大大增加了测试时间。该组件也已经在其他地方进行了测试。
看看一个非常相似的问题