用笑话和酶模拟自定义 Hook 导致“xxx 不是函数或其返回值不可迭代”错误

问题描述

我对玩笑和酶很陌生。在我的项目中,我将使用基于 SPA React 的应用程序。包含数据的上下文提供程序,还有几个钩子。我现在使用 Jest(使用 ts-jest 和酶)

我的 jest.config 看起来像这样

module.exports = {
  "roots": [
    "<rootDir>/src"
  ],"transform": {
    "^.+\\.tsx?$": "ts-jest"
  },"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$","modulefileExtensions": [
    "ts","tsx","js","jsx","json","node"
  ],"snapshotSerializers": ["enzyme-to-json/serializer"]

所以我的第一步是测试 UI 组件是否有效。 下一步是使用模拟数据测试组件。但是我得到了底部描述的错误

我有一个这样的功能组件:

export default function CurrentWeather(props: ICurrentWeatherProps) {
    const [data,Reload] = useCurrentWeather(props.locationID);
    return (<div>......</div>)
}

您会注意到 useCurrentWeather 钩子,这是它的代码

import { useEffect,useState } from 'react';
import { useLocationState } from '../context/locationContext';
import { ILocationData } from './useLocations';
import _ from 'lodash';

...


export default function useCurrentWeater(locationId: number) {

    const locationState = useLocationState();

    const Reload = () => { GetData() }
    const [Data,SetData] = useState<IWeatherDataInfo>({Id:0,ConditionIcon:'',Date:new Date(),MaxTemp:0,MinTemp:0});

    async function GetData() { .... }
    useEffect(Reload,[locationState.data,locationId]);
    return [Data,Reload] as const;
}

现在我想嘲笑这些 Hook。我尝试了以下

import React from 'react';
import { configure,shallow,mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import CurrentWeather from '../components/Weather/CurrentWeather';
import { IWeatherDataInfo } from '../Hooks/useWeaters';
configure({ adapter: new Adapter() });


const mockWeatherReload = jest.fn();
const mockdata: IWeatherDataInfo = { Date: new Date(),ConditionIcon: "",MinTemp: 0,MaxTemp: 10 };


jest.mock('../Hooks/useCurrentWeather',() => ({
  useCurrentWeather: jest.fn(()=>{ [mockdata,mockWeatherReload]}) 
}));

describe("WeatherWidget",() => {
  it("RenderOnlyAddButton",() => {
    const container = shallow(<CurrentWeather locationID={1} hidden={false} />);
  });
});

现在,当我执行这个测试时,我会得到这个错误结果:

src/tests/WeatherWidget.test.tsx
  ● WeatherWidget › RenderOnlyAddButton

    TypeError: (0,_useCurrentWeather.default) is not a function or its return value is not iterable

       9 | 
      10 | export default function CurrentWeather(props: ICurrentWeatherProps) {
    > 11 |     const [data,Reload] = useCurrentWeather(props.locationID);
         |                            ^
      12 |     return (

在这里做错了什么?有什么我遗漏的吗?

解决方法

试试这个:(下面应该是你的功能组件的测试文件)

const mockUseCurrentWeather = jest.fn();

jest.mock("put here the absolute path",() => ({
  __esModule: true,useCurrentWeather: (...args: any) => mockUseCurrentWeather(...args),}));
describe("WeatherWidget",() => {
beforeEach(() => {
    mockUseCurrentWeather.mockClear();
    mockUseCurrentWeather.mockReturnValue([undefined,undefined]);

    
  });

  it("RenderOnlyAddButton",() => {
mockUseCurrentWeather.mockClear();
    mockUseCurrentWeather.mockReturnValue([undefined,undefined]);
    const container = shallow(<CurrentWeather locationID={1} hidden={false} />);
  });
});

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...