Обновление TestHook внутри теста не было установлено (...) - PullRequest
0 голосов
/ 04 мая 2020

Я использую хуки для визуализации компонентов пользовательского интерфейса и пытаюсь их протестировать.

import React, { useState, useCallback } from 'react';
import { useModal } from './useModal';
import { ConfirmationModal } from './common';

export const useConfirm = () => {
  // Manage if confirm module is open or close
  // Provide callback to set confirm state
  const { isShowing, toggle } = useModal();

  // Track confirmation module values
  const [confirmOptions, setConfirmOptions] = useState({});

  // Callback to set confirmation model properties
  const setConfirmation = useCallback(
    async (title, body, onConfirm, onCancel) => {
      await setConfirmOptions({
        title,
        body,
        onConfirm,
        onCancel
      });
      toggle();
    },
    [toggle]
  );

  const ConfirmModal = (
    <ConfirmationModal
      open={isShowing}
      toggle={toggle}
      title={confirmOptions.title}
      content={confirmOptions.body}
      onConfirm={confirmOptions.onConfirm}
      onCancel={confirmOptions.onCancel}
    />
  );

  return {
    setConfirmation,
    ConfirmModal
  };
};

Тест:

import { renderHook, act } from '@testing-library/react-hooks';
import { useConfirm } from './useConfirm';

describe('useConfirm hook', () => {
  it('toggles confirm ui', () => {
    const { result } = renderHook(() => useConfirm());
    const onConfirm = jest.fn();
    const onCancel = jest.fn();
    // test confirm is called
    act(() => {
      result.current.setConfirmation(
        'Title',
        'Content Content',
        onConfirm,
        onCancel
      );

      console.log(result.current.ConfirmModal);
    });
    // test cancel is called
  });
});

Я получаю:

Warning: An update to %s inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

Но это обертка.

Ответы [ 2 ]

0 голосов
/ 07 мая 2020

Эта проблема может быть вызвана анимацией, в этом случае вы можете решить эту проблему с помощью имитации таймеров с помощью Jest:

describe('...', () => {
  beforeAll(() => {
    jest.useFakeTimers();
  });

  afterAll(() => {
    jest.useRealTimers();
  });
  // ...
});
0 голосов
/ 04 мая 2020

Эта ошибка обычно возникает, когда вы пытаетесь подтвердить, прежде чем компонент завершит обновление всех состояний.

Обратите внимание, что внутри setConfirmation вы вызываете toggle(), и это обновляет состояние.

Вы должны использовать что-то вроде waitFor , чтобы дождаться обновления значения переключателя или вызова обещания.

Я не знаком с библиотекой render-hooks, но, возможно, приведенный ниже пример поможет вам. Я также оставлю некоторые полезные ссылки внизу.

  it('toggles confirm ui', async () => {
    const { result } = renderHook(() => useConfirm());
    const onConfirm = jest.fn();
    const onCancel = jest.fn();

    // test confirm is called    
    result.current.setConfirmation(
      'Title',
      'Content Content',
      onConfirm,
      onCancel
    );

    await waitFor(() => expect(onConfirm).toHaveBeenCalled());
    // or await for something to appear on the screen
  });

Что такое act() из React документы :

При написании Тесты пользовательского интерфейса, такие задачи, как рендеринг, пользовательские события или выборка данных, можно рассматривать как «единицы» взаимодействия с пользовательским интерфейсом. React предоставляет вспомогательный метод act (), который гарантирует, что все обновления, связанные с этими «модулями», были обработаны и применены к DOM, прежде чем вы сделаете какие-либо утверждения.

Имя act происходит от Arrange-Act-Assert pattern.


Полезные ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...