Jak mogę sprawdzić, czy rekwizyt został przekazany dziecku?
Mój komponent wygląda mniej więcej tak: (ma więcej funkcji i kolumn, ale nie uwzględniłem tego, aby uprościć przykład)
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} />
);
};
Teraz napisałem kilka testów w ten sposób:
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(),
);
});
Jeśli zaznaczysz mój komponent, ma on zmienną o nazwie kolumny. Przypisuję tę zmienną do komponentu tabeli.
Myślę, że powinienem sprawdzić, czy kolumny są przekazywane jako rekwizyty do komponentu tabeli. Czy dobrze myślę? Jeśli tak, czy możesz mi powiedzieć, jak mam napisać do tego przypadek testowy?
Pomocne będzie również, jeśli możesz mi zasugerować, jak mogę przetestować każdą komórkę zadeklarowaną wewnątrz właściwości column.
Odpowiedzi
Nie zaleca się testowania szczegółów implementacji, takich jak właściwości komponentów, za pomocą biblioteki testowania React. Zamiast tego powinieneś potwierdzać zawartość ekranu.
Zalecana
expect(await screen.findByText('some city')).toBeInTheDocument();
expect(screen.queryByText('filtered out city')).not.toBeInTheDocument();
Niepolecane
Jeśli mimo wszystko chcesz przetestować rekwizyty, możesz wypróbować poniższy przykładowy kod. Źródło
import Table from './Table'
jest.mock('./Table', () => jest.fn(() => null))
// ... in your test
expect(Table).toHaveBeenCalledWith(props, context)
Możesz rozważyć to podejście głównie w dwóch poniższych scenariuszach.
Wypróbowałeś już zalecane podejście, ale zauważyłeś, że komponent to:
- przy użyciu starszego kodu iz tego powodu bardzo utrudnia testowanie. Refaktoryzacja komponentu również zajęłaby zbyt dużo czasu lub byłaby zbyt ryzykowna.
- jest bardzo powolny i drastycznie wydłuża czas testowania. Komponent został już przetestowany w innym miejscu.
spójrz na bardzo podobne pytanie tutaj
Możesz użyć tej props()
metody, robiąc coś takiego:
expect(Table.props().propYouWantToCheck).toBeFalsy();
Po prostu wykonując komponent.props (), a następnie żądany atrybut, możesz wykonać z nim dowolny asercję.