如何在Jest和react-testing-library中使用react-hook

时间:2019-03-26 16:28:52

标签: javascript reactjs antd react-hooks react-testing-library

我在使用react挂钩的测试组件方面遇到问题。 我需要测试单击按钮后,是否在更新蚂蚁设计范围选择器内的日期范围。为了进行测试,我使用了Jest和react-testing-library。

此时,它看起来像这样:(其中一些嵌套组件只是样式组件:))

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 但是看起来这是用于自定义钩子的吗?

也许这个测试用例有一个解决方案,而没有使用react-hooks?任何想法高度赞赏。 :)

1 个答案:

答案 0 :(得分:4)

您必须渲染Parent,因为它包含更新DateSelect的逻辑。这样可以进行更好的测试,因为您正在测试组件之间的集成是否有效。