Фермент mount () перерисовывается после изменения состояния в useEffect ()? - PullRequest
0 голосов
/ 17 апреля 2020

Я новичок в React и модульном тестировании React. У меня есть компонент, который загружает некоторые div в зависимости от состояния, установленного с помощью useState. Внутри useEffect, если из функции возвращается отклоненное обещание, вместо этого должен отображаться div div. Я хочу протестировать этот сценарий, но поскольку исходное состояние установлено как error = false, вместо этого по-прежнему отображаются исходные div.

Мой вопрос: как я могу сделать это, чтобы тест регистрировал обновленные div? Я использую Enzyme's mount (), но я также попробовал его с мелкой (). Я также подтвердил, что он на самом деле входит в .catch () с некоторыми console.logs.

component:

export const Main = (props) => { 
  const [showLoadError, setShowLoadError] = useState(false);
  const [loadError, setLoadError] = useState('');

  React.useEffect(() => {
    const { categories, actions } = props;

    // retrieve categories from Db if they don't exist in state
    if (categories.length === 0) {
      actions.loadCategories().catch(err => {
        setShowLoadError(true);
        setLoadError(err.message);
      })
    } else {
      setShowLoadError(false);
      setLoadError('');
    }
  }, []);

  return (

    <>
      {/* conditional show for error container if loading failed */}
      {showLoadError &&
        <div className="load-error">
          Error loading categories. {loadError}
        </div>
      }
      {/* conditional show for no Load error */}
      {!showLoadError &&
        <div className="grid-container grid-container--fit">
          <div><CategoryContainer /></div>
          <div><ItemContainer /></div>
          <div><FileAssociationsContainer /></div>
        </div>
      }
    </>
  );
}

test:

import React from 'react';
import ConnectedApp, { Main } from './Main';
import { shallow, mount } from 'enzyme';

jest.mock("../category/CategoryContainer");
jest.mock("../item/ItemContainer");
jest.mock("../fileAssociations/FileAssociationsContainer");

describe("Main component", () => {

  beforeEach(() => {
    fetch.resetMocks()
  });

  test('should render error div after loadCategories fail',  () => {
    const categories = [];
    const errMessage = {message: 'test error'}
    const actions = {
      loadCategories: jest.fn(() => {
        return Promise.reject(errMessage);
      })
    };

    const wrapper = mount(<Main categories={categories} actions={actions} />);

    wrapper.setProps(); // rerenders

    // expect there to be a load-error div
    expect(wrapper.find('div').hasClass('load-error')).toBe(true)

    // expect loadCategories to be called because component was passed in empty categories
    expect(actions.loadCategories).toBeCalled();

  });



});

I ' мы пытались wrapper.setProps(), wrapper.update() до того, как мои ожидания не увенчались успехом.

Кроме того, этот юнит-тест дает шутливое предупреждение о том, что An update to Main inside a test was not wrapped in act(...). Это происходит только в том случае, если actions.loadCategories () возвращает отклоненное обещание. Он не делает этого, когда возвращает разрешенное обещание. Я пытался переместить код в act (), но безуспешно удалял ошибку, например:

act(() => {
      actions = {
        loadCategories: jest.fn(() => {
          return Promise.reject(errMessage);
        })
      };
      wrapper = mount(<Main categories={categories} actions={actions} />);
      wrapper.setProps(); // rerenders
    });
...