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

Sas*_*zak 4 jestjs enzyme react-scripts ts-jest react-typescript

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

\n

我的 jest.config 看起来像这样

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

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

\n

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

\n
export default function CurrentWeather(props: ICurrentWeatherProps) {\n    const [data, Reload] = useCurrentWeather(props.locationID);\n    return (<div>......</div>)\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n

您会注意到这个useCurrentWeather钩子,这是其代码:

\n
import { useEffect, useState } from 'react';\nimport { useLocationState } from '../context/locationContext';\nimport { ILocationData } from './useLocations';\nimport _ from 'lodash';\n\n...\n\n\nexport default function useCurrentWeater(locationId: number) {\n\n    const locationState = useLocationState();\n\n    const Reload = () => { GetData() }\n    const [Data, SetData] = useState<IWeatherDataInfo>({Id:0,ConditionIcon:'',Date:new Date(),MaxTemp:0, MinTemp:0});\n\n    async function GetData() { .... }\n    useEffect(Reload, [locationState.data, locationId]);\n    return [Data, Reload] as const;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

现在我想嘲笑这些 Hook。我尝试跟随

\n
import React from 'react';\nimport { configure, shallow, mount } from 'enzyme';\nimport Adapter from 'enzyme-adapter-react-16';\nimport CurrentWeather from '../components/Weather/CurrentWeather';\nimport { IWeatherDataInfo } from '../Hooks/useWeaters';\nconfigure({ adapter: new Adapter() });\n\n\nconst mockWeatherReload = jest.fn();\nconst mockdata: IWeatherDataInfo = { Date: new Date(), ConditionIcon: "", MinTemp: 0, MaxTemp: 10 };\n\n\njest.mock('../Hooks/useCurrentWeather', () => ({\n  useCurrentWeather: jest.fn(()=>{ [mockdata, mockWeatherReload]}) \n}));\n\ndescribe("WeatherWidget", () => {\n  it("RenderOnlyAddButton", () => {\n    const container = shallow(<CurrentWeather locationID={1} hidden={false} />);\n  });\n});\n\n
Run Code Online (Sandbox Code Playgroud)\n

现在,当我执行此测试时,我将得到以下错误结果:

\n
src/tests/WeatherWidget.test.tsx\n  \xe2\x97\x8f WeatherWidget \xe2\x80\xba RenderOnlyAddButton\n\n    TypeError: (0 , _useCurrentWeather.default) is not a function or its return value is not iterable\n\n       9 | \n      10 | export default function CurrentWeather(props: ICurrentWeatherProps) {\n    > 11 |     const [data, Reload] = useCurrentWeather(props.locationID);\n         |                            ^\n      12 |     return (\n
Run Code Online (Sandbox Code Playgroud)\n

我在这里做错了什么?我有缺少什么吗?

\n

Sak*_*shi 5

尝试这样:(下面应该是您的功能组件的测试文件)

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} />);
  });
});

Run Code Online (Sandbox Code Playgroud)