Должен ли я вручную вызывать размонтирование renderHook в библиотеке реагирования-тестирования?

В документации библиотеки React Testing говорится, что не нужно выполнять очистку после каждого теста, но в документации renderHook ничего не сказано, если unmount вызывается после завершения теста.

Так нужно ли вызывать unmount в тестах с помощью renderHook?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
157
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам не нужно вызывать функцию RTL очистки , когда вы используете renderHook() , из исходного кода мы знаем, что она вызывает функцию render с помощью <TestComponent/>. Так

cleanup вызывается автоматически после каждого теста по умолчанию, если используемая вами среда тестирования поддерживает глобальный afterEach (например, Mocha, Jest и Jasmine).

function renderHook(renderCallback, options = {}) {
  const {initialProps, ...renderOptions} = options

  if (renderOptions.legacyRoot && typeof ReactDOM.render !== 'function') {
    const error = new Error(
      '`legacyRoot: true` is not supported in this version of React. ' +
        'If your app runs React 19 or later, you should remove this flag. ' +
        'If your app runs React 18 or earlier, visit https://react.dev/blog/2022/03/08/react-18-upgrade-guide for upgrade instructions.',
    )
    Error.captureStackTrace(error, renderHook)
    throw error
  }

  const result = React.createRef()

  function TestComponent({renderCallbackProps}) {
    const pendingResult = renderCallback(renderCallbackProps)

    React.useEffect(() => {
      result.current = pendingResult
    })

    return null
  }

  const {rerender: baseRerender, unmount} = render(
    <TestComponent renderCallbackProps = {initialProps} />,
    renderOptions,
  )

  function rerender(rerenderCallbackProps) {
    return baseRerender(
      <TestComponent renderCallbackProps = {rerenderCallbackProps} />,
    )
  }

  return {result, rerender, unmount}
}

Если вы хотите протестировать логику кода в функции cleanup хука useEffect(), вам следует вызвать функцию ummount(). См. пример ниже:

import { renderHook, screen } from '@testing-library/react';
import React, { useEffect } from 'react';

describe('78435539', () => {
  test('should pass', () => {
    const Context = React.createContext('default');
    function Wrapper({ children }) {
      return (
        <Context.Provider value = "provided">
          <h1>Provider 1</h1>
          {children}
        </Context.Provider>
      );
    }
    const { result } = renderHook(() => React.useContext(Context), { wrapper: Wrapper });
    expect(result.current).toEqual('provided');
    screen.debug();
  });

  test('should pass 2', () => {
    const Context = React.createContext('default');
    function Wrapper({ children }) {
      return (
        <Context.Provider value = "provided">
          <h1>Provider 2</h1>
          {children}
        </Context.Provider>
      );
    }
    const { result } = renderHook(() => React.useContext(Context), { wrapper: Wrapper });
    expect(result.current).toEqual('provided');
    screen.debug();
  });

  test('should pass 3', () => {
    let count = 0;
    const { unmount } = renderHook(() => {
      useEffect(() => {
        const onClick = () => {
          count++;
        };
        document.body.addEventListener('click', onClick);
        return () => {
          document.body.removeEventListener('click', onClick);
        };
      }, []);
    });

    document.body.click();
    expect(count).toBe(1);
    unmount();
    document.body.click();
    expect(count).toBe(1);
  });
});

Результат испытаний:

> jest -o

  console.info
    <body>
      <div>
        <h1>
          Provider 1
        </h1>
      </div>
    </body>

      at logDOM (node_modules/@testing-library/dom/dist/pretty-dom.js:87:13)

  console.info
    <body>
      <div>
        <h1>
          Provider 2
        </h1>
      </div>
    </body>

      at logDOM (node_modules/@testing-library/dom/dist/pretty-dom.js:87:13)

 PASS  stackoverflow/78435539/index.test.tsx
  78435539
    √ should pass (32 ms)
    √ should pass 2 (5 ms)
    √ should pass 3 (2 ms)

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        1.044 s
Ran all test suites related to changed files.

Другие вопросы по теме