如何在没有触发事件(如单击)的情况下测试钩子

时间:2020-03-11 09:46:28

标签: reactjs jestjs react-hooks react-testing-library

只要有某种类型的onClick,onChange等,似乎有很多关于如何对钩子进行测试的方法,但是如果您将该函数传递给事件处理组件(如我在下面),该怎么办?

const Content: FC<Props> = ({ activeTab }) => {
  const [count, setCount] = useState<number>(0);

  function handleDateUpdate(dates: object) {
    const totalCount = new GetTotal(dates, activeTab);
    setCount(totalCount.totalAttendances());
  }

  useEffect(() => {
    if (activeTab === 'Year') {
      handleDateUpdate(new Date());
    }
  });

  return (
    <Container>
        {activeTab === 'Month' && (
          <Datepicker handleDateUpdate={handleDateUpdate} />
        )}
      <TotalAttendences count={count} />
    </Container>
  );
}

我想编写一个测试来检查useEffect和handleDateUpdate中的if语句,以确保它正在执行我想要的操作。

1 个答案:

答案 0 :(得分:0)

如果要测试是否已调用handleDateUpdate,建议将其提取到帮助文件中,然后使用export function导出。然后,通过执行以下操作将整个帮助程序文件导入到定义组件的文件中: import * as dateHelpers from '../path/to/file';

这样,当您在组件中调用函数时,您将以dateHelpers.handleDateUpdate的身份进行操作。这将确保正确注入依赖项,以便您可以监视在组件中调用的handleDateUpdate函数的实例,以确保正确(或不正确)调用该依赖关系。

由于activeTab<Content />的道具,因此我将通过以下操作来测试useEffect

import { shallow } from enzyme;
// I'm using enzyme here, but you could use whatever React testing library you choose
import * as dateHelpers from '../path/to/file/'

describe('<Content />', () => {
  let dateUpdateSpy;
  beforeEach(() => {
    dateUpdateSpy = jest.spyOn(dateHelpers, 'handleDateUpdate'); 
  })

  afterEach(() => {
    jest.clearAllMocks()
  })

  it('should invoke handleDateUpdate() when the activeTab prop equals "Year"'), () 
  => {
    shallow(<Content activeTab="Year" />);

    expect(dateUpdateSpy).toHaveBeenCalledWith(new Date());
  }


  it('should not invoke handleDateUpdate() when the activeTab prop does not equal 
  "Year"'), () => {
    shallow(<Content activeTab="Month" />);

    expect(dateUpdateSpy).not.toHaveBeenCalled();
  }
}

最后,您应该将activeTab作为对useEffect的依赖,因为您只想在activeTab更改时运行该回调函数。它将在挂载上运行,但是如果由于activeTab更改以外的其他原因进行了重新渲染,则您将不必要地重新运行useEffect。所以我将其更改为:

useEffect(() => {
  if (activeTab === 'Year') {
    dateHelpers.handleDateUpdate(new Date());
  }
}, [activeTab]);
``