使用 React 测试库时尝试解构 non-iterable 实例无效

Invalid attempt to destructure non-iterable instance while using react testing library

我正在尝试为我的 React App 做一个功能测试,我的组件有一个 div 和 data-testid="btnHeaderCategory",点击 div 我必须更新样式body 我正在使用 React 和 react testing library 进行单元测试。

我正在更新 body 的样式 document.body.style.overflow = "hidden";

这是我的组件

import React, {useState} from "react";

const Main = () => { 
    const [flag, updateFlag] = useState(false);
    const getCategory = () => {
        updateFlag(true);
        document.body.style.overflow = "hidden";
    }
    return(
        <div onClick={getCategory} data-testid="btnHeaderCategory">
            {flag ? <div data-testid="megaMenu" > New categories </div> : ""}
        </div>
    )
}

export default Main;

这是我的测试文件

import { render, fireEvent, cleanup, waitForElement } from '@testing-library/react';

describe("components/Main",()=>{
    let Main;

    beforeAll(()=>{
      Main = require('./Main').default;

    });
    afterAll(() => {
      cleanup();
    });
    test("Test if categories shown", async()=>{

      const { getByTestId } = render(
        <Main />
      );
      fireEvent.click(getByTestId('btnHeaderCategory'));
      const elem = getByTestId('megaMenu'));
      expect(elem).toBeInTheDocument();

    });
})

当我尝试 运行 测试时,它因以下错误而中断

TypeError:解构non-iterable实例的尝试无效

玩笑配置


var baseConfig = {
   collectCoverageFrom: [
    '<rootDir>/**/*.js',
    '!**/node_modules/**',
    '!<rootDir>/coverage/**',
    '!<rootDir>/jest.config.js',
    '!**/__tests__/**',
  ],
  coverageThreshold: {
    global: {
      statements: 100,
      branches: 100,
      functions: 100,
      lines: 100,
    },
  },
};

module.exports = {
  ...baseConfig,
  collectCoverageFrom: [baseConfig.collectCoverageFrom, '!<rootDir>/build/**'],
  coverageReporters: ['json', 'lcov', 'text', 'clover', 'html'],
  coverageThreshold: {
    global: {
      statements: 0.5,
      branches: 0.1,
      functions: 0.1,
      lines: 0.5,
    },
  },
  projects: [
    createProject({
      displayName: 'Configuration',
      testMatch: ['<rootDir>/__tests__/**/*.js'],
      testEnvironment: 'node',
    }),
    createProject({

      displayName: 'Client',
      testMatch: ['<rootDir>/client/**/__tests__/**/*.js'],
      testEnvironment: 'jsdom',

    }),
  ],
}

我刚刚尝试过,它对我有用...您可以通过以下方式简化测试:

import * as React from 'react';
import { render, fireEvent } from '@testing-library/react';

import Main from './Main';

describe('components/Main', () => {
  test('Test if categories shown', () => {
    const { getByTestId } = render(<Main />);

    fireEvent.click(getByTestId('btnHeaderCategory'));
    expect(getByTestId('megaMenu')).toBeDefined(); //Or to be in the document
  });
});

同样在 Main.js 上,我会避免将 "" 作为 children 放在 div 上,只需更改:{flag && <div data-testid="megaMenu" > New categories </div>},并添加对 document.body -> if (document.body) document.body.style.overflow = 'hidden'; 进行空检查...因为它可能是 null.

通过为 custom hook

提供上下文解决了这个问题

我在我的主要组件中使用了一个 React 自定义挂钩,它破坏了测试并且错误消息是错误的,这让我感到困惑。

在使用 React 测试库时解构不可迭代实例的尝试无效

使用 react-hooks-testing-library 中的 renderHook 解决了问题,我的测试用例现在工作正常。

这是我找的零钱

import GlobalProvider, { GlobalContext } from '@context/global';

const { globalState } = renderHook(() => useContext(GlobalContext));

const { getByTestId } = render(
    <GlobalProvider value={globalState}>
      <Main />
    </GlobalProvider>,
);