Как использовать реактив-хуки с библиотекой Jest и реагировать на тестирование - PullRequest
2 голосов
/ 26 марта 2019

У меня проблема с компонентом тестирования, который использует реакционные хуки.Мне нужно проверить, обновляется ли после нажатия кнопки диапазон дат внутри выбора диапазона дизайна муравья.Для тестирования я использую Jest и response-testing-library.

На данный момент это выглядит следующим образом: (некоторые из этих вложенных компонентов являются просто styleled-компонентами :))

Parent.jsx:

 const Parent = () => {
  const [dateRange, setDateRange] = useState([moment(), moment()]);
  return (
    <div>
      <Sidebar
        visible={sidebarVisible}
        setSidebarVisible={setSidebarVisible}
        setTableData={setTableData}
        setStatementsLength={setStatementsLength}
        setDateRange={setDateRange}
        dateRange={dateRange}
      />
    </div>
  );
};

export default Parent;

Sidebar.jsx:

const Sidebar = props => {
  return (
    <div>
      <Drawer
        placement="left"
        closable={false}
        onClose={() => props.setSidebarVisible(false)}
        visible={props.visible}
        width={488}
        bodyStyle={drawerStyle}
      >
        <DrawerContent data-test-id="statementsSidebar">
          <DrawerHeader data-test-id="statementsSidebarHeader">
            {t('settlements.statements.sidebar.createQuery')}
          </DrawerHeader>
          <DrawerBody>
            <DateSelect
              dateRange={props.dateRange}
              setDateRange={props.setDateRange}
            />
          </DrawerBody>
          <DrawerFooter/>
        </DrawerContent>
      </Drawer>
    </div>
  );
};

export default Sidebar;

DateSelect.jsx:

const DateSelect = props => {
  const RangePicker = DatePicker.RangePicker;
  const [offset, setOffset] = useState(0);
  const timeUnit = Object.freeze({ day: 'd', week: 'w', month: 'm' });
  const [offsetUnit, setOffsetUnit] = useState(timeUnit.day);

  const setRangeToLastWeek = () => {
    if (offset > 0) {
      props.setDateRange([
        moment().subtract(1, 'w'),
        moment().add(offset, 'd'),
      ]);
    } else if (offset < 0) {
      props.setDateRange([
        moment()
          .subtract(1, 'w')
          .add(offset, 'd'),
        moment(),
      ]);
    } else {
      props.setDateRange([moment().subtract(1, 'w'), moment()]);
    }
    setOffsetUnit('w');
  };

 const manuallySetDate = range => {
    setOffset(0);
    props.setDateRange(range);
  };

  return (
    <div>
      <HeaderRow/>
      <DateSelectorRow>
          <ButtonsColumn>
            <Button
              value="lastWeek"
              onClick={setRangeToLastWeek}
              style={styleButtonPadding}
              data-test-id="setRangeToLastWeek"
              data-testid="lastWeekButton"
            >
              Last 7 days
            </Button>
          </ButtonsColumn>
        <div data-testid="range-picker-value">
        <RangePicker
          value={props.dateRange}
          format={DateFormat}
          onChange={v => manuallySetDate(v)}
        />
        </div>
      </DateSelectorRow>
    </div>
  );
};

export default DateSelect;

DateSelect.test.js:

 it('After clicking last 7 days button date range is changed', () => {
    // const setDateRange = ??????
     const range = [moment(), moment()];
     const { container } = render(<DateSelect setDateRange={setDateRange} dateRange={range}/>);
     const startDate = getByPlaceholderText(container, 'Start date');
     const endDate = getByPlaceholderText(container, 'End date');
     const lastWeekButton = getByTestId(container,'lastWeekButton');
     expect(startDate.value).toBe(moment().format(DateFormat));
     expect(endDate.value).toBe(moment().format(DateFormat));
     fireEvent.click(lastWeekButton);
     expect(startDate).toBe(moment().subtract(1, 'w').format(DateFormat));
     expect(endDate.value).toBe(moment().format(DateFormat));
   });

Как и ожидалось, поскольку я не передаю функцию setDateRange в качестве опоры компоненту DateSelect внутри теста, значение диапазона не изменяется.Я попытался добавить хук в тесте так:

const [dateRange, setDateRange] = [moment(), moment()];

Но я получаю: Хуки можно вызывать только внутри тела компонента функции. ТакЯ предполагаю, что не могу использовать это там.Есть ли какое-то решение этого?Как указать функцию setDateRange внутри теста, которая будет действовать как ловушка?

Я нашел это: https://github.com/mpeyper/react-hooks-testing-library Но похоже, что это для пользовательских ловушек?

Может быть, есть решение для этого тестового примера, которое не использует ответные зацепки?Любые идеи высоко ценятся.:)

1 Ответ

4 голосов
/ 26 марта 2019

Вы должны отрендерить Parent, поскольку он содержит логику для обновления DateSelect.Это делает тест лучше, потому что вы проверяете, что интеграция между компонентами работает.

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