Comment puis-je tester si un accessoire est transmis à un enfant?
Mon composant ressemble à quelque chose comme ceci: (Il a plus de fonctionnalités ainsi que des colonnes, mais je ne l'ai pas inclus pour rendre l'exemple plus simple)
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} />
);
};
Maintenant, j'ai écrit quelques tests comme celui-ci:
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(),
);
});
Si vous vérifiez mon composant, il a une variable appelée colonnes. J'attribue cette variable au composant Table.
Je pense que je devrais tester que les colonnes sont passées comme accessoires au composant Table. Est-ce que je pense bien? Si oui, pouvez-vous me dire comment puis-je rédiger un scénario de test pour cela?
En outre, il sera utile si vous pouvez me suggérer comment puis-je tester chaque cellule déclarée à l'intérieur de la propriété des colonnes.
Réponses
Il n'est pas recommandé de tester les détails de l'implémentation, tels que les accessoires de composant, avec React Testing Library. Au lieu de cela, vous devriez vous affirmer sur le contenu de l'écran.
conseillé
expect(await screen.findByText('some city')).toBeInTheDocument();
expect(screen.queryByText('filtered out city')).not.toBeInTheDocument();
Non recommandé
Si vous souhaitez quand même tester les accessoires, vous pouvez essayer l'exemple de code ci-dessous. La source
import Table from './Table'
jest.mock('./Table', () => jest.fn(() => null))
// ... in your test
expect(Table).toHaveBeenCalledWith(props, context)
Vous pouvez envisager cette approche principalement dans les deux scénarios suivants.
Vous avez déjà essayé l'approche recommandée mais vous avez remarqué que le composant est:
- en utilisant du code hérité et à cause de cela, cela rend les tests très difficiles. Refactoriser le composant prendrait également trop de temps ou serait trop risqué.
- est très lent et augmente considérablement le temps de test. Le composant est également déjà testé ailleurs.
jetez un œil à une question très similaire ici
Vous pouvez utiliser la props()
méthode en faisant quelque chose comme ceci:
expect(Table.props().propYouWantToCheck).toBeFalsy();
En faisant simplement votre component.props () puis l'accessoire que vous voulez, vous pouvez faire n'importe quelle affirmation avec.