Comment puis-je tester si un accessoire est transmis à un enfant?

Nov 20 2020

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

1 Doug Nov 21 2020 at 04:41

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:

  1. 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é.
  2. 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

2 OtacílioMaia Nov 21 2020 at 02:45

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.