使用 useState 进行 Vitest 和 React 测试库错误测试组件:TypeError:无法读取 null 的属性(读取 'useState')

问题描述 投票:0回答:1

我正在关注一些关于如何在我的 vite 项目中设置 vitest 和测试库的视频...基本上我已经在我的 package.json 中安装了依赖项

"devDependencies": {
        "@testing-library/react": "^16.0.1",
        "@types/react": "^18.3.3",
        "@vitejs/plugin-react": "^4.3.1",
        "globals": "^15.9.0",
        "jsdom": "^25.0.0",
        "vite": "^5.4.1",
        "vitest": "^2.1.1"
    }

更新了我的 vite 配置

/// <reference types="vite/client" />
/// <reference types="vitest" />

import path from 'node:path'
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vitest/config'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react({
      jsxImportSource: '@emotion/react',
      babel: {
        plugins: ['@emotion/babel-plugin'],
      },
    }),
  ],
  test: {
    globals: true,
    environment: 'jsdom',
    css: true,
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
      '@components': path.resolve(__dirname, './src/components'),
    },
  },
})

并将此类型添加到我的 tsconfig.json

"compilerOptions": {
    "paths": {
        "@components/*": ["./src/components/*"],
        "@/*": ["./src/*"]
    },
    "jsxImportSource": "@emotion/react",
    "types": [
        "@emotion/react/types/css-prop",
        "reflect-metadata",
        "jest",
        "vitest/globals",
        "@testing-library/jest-dom"
    ],
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "allowUmdGlobalAccess": true
},

到目前为止一切顺利...现在我编写一些简单的测试

import { useState } from 'react'


console.log('React version:', React.version);
console.log('useState available:', typeof React.useState);

export const ComponentWithState = () => {
  const [counter, setCounter] = useState(0)

  return <div>
    Counter: {counter}
     
    <button type="button" onClick={() => setCounter(counter + 1)}>Increment</button>
  </div>
}

和我的测试在同一个文件夹中

import { fireEvent, render, screen } from '@testing-library/react'
import {ComponentWithState} from './ComponentWithState'

console.log('Test file: React version:', React.version);
console.log('Test file: useState available:', typeof React.useState);

describe('tests', () => {
  it('should be true', () => {
    expect(true).toBe(true)
  })

  it('should render', () => {
    render(<div>Hello</div>)
    expect(screen.getByText('Hello')).toBeDefined()
  })

  it('should increment in ComponentWithState', () => {
    render(<ComponentWithState />)
    expect(screen.getByText('Counter: 0')).toBeDefined()
    fireEvent.click(screen.getByText('Increment'))
    expect(screen.getByText('Counter: 1')).toBeDefined()
  })
})

前两个测试通过,但 ComponentWithState 应该增加失败

错误是这样的

Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.


Error: Uncaught [TypeError: Cannot read properties of null (reading 'useState')]
at reportException (/<my path>/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)

但似乎 useState 不为空,根据日志是一个函数

React version: 18.3.1
useState available: function
Test file: React version: 18.3.1
Test file: useState available: function

我检查了一些教程,这些教程使用了 useState 和 React 测试库,没有任何问题,不知道为什么会出现此错误。

任何帮助将不胜感激 非常感谢你

reactjs react-testing-library vitest
1个回答
0
投票

您是否已检查错误消息中的链接

您可能会看到它的三个常见原因:

  1. 您可能违反了 Hooks 规则。

  2. 您的 React 和 React DOM 版本可能不匹配。

  3. 您可能在同一个应用程序中拥有多个 React 副本。

第一点似乎并非如此。

对于数字 2:

您可以在应用程序文件夹中运行

npm ls react-dom
[...]来检查您正在使用哪个版本。

对于 3 号:

您可以在应用程序文件夹中运行

npm ls react
来检查您正在使用哪个版本。

© www.soinside.com 2019 - 2024. All rights reserved.