reactjs - 我如何測試一個 prop 是否被傳遞給子組件?
我的元件看起來大致如下:(它還有更多功能以及欄位,但我為了簡化範例未包含那些部分)
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(),
);
});
如果你查看我的元件,它有一個名為 columns 的變數。我正在將該變數分配給 Table 元件。
我認為,我應該測試那些欄位是否被作為 props 傳遞給 Table 元件。我想的對嗎?如果是的話,你能告訴我該如何為此寫測試案例嗎?
此外,如果你能建議我如何測試宣告在 columns 屬性內的每個儲存格,將會很有幫助。
答案#1
不建議使用 React Testing Library 測試實作細節,例如組件的 props。相反地,你應該對畫面內容進行斷言。
推薦
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)
你可能主要在以下兩種情況下考慮這種方法。
您已經嘗試了建議的方法,但您注意到該元件是:
- 使用舊有的程式碼,因此這使得測試變得非常困難。重構這個元件也會花費太多時間或風險太大。
- 非常慢,並且大幅增加了測試時間。該元件也已經在其他地方進行過測試。
在這裡看看一個非常相似的問題
