You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Remix.js+TypeScript环境下Jest测试报setState错误求助

问题描述

我正在用Remix.js搭配TypeScript开发,移除jest.config.js时测试套件能正常运行,但保留该文件就会抛出错误:"TypeError: (0 , _expect.setState) is not a function"。我必须保留这个配置文件来处理TypeScript测试的转译,目前自己排查不出问题,哪怕是极简配置也会触发这个错误。


相关代码与配置

service.test.ts

import { fetch } from '@remix-run/node'

import { getGames, mapGamesData } from '../api/service'

const mockFetch = fetch as jest.MockedFn<typeof fetch>
const mockResponse = (mockData: any): Response =>
  ({ json: async () => mockData } as Response)

const mockGames = {
  data: [
    {
      id: 857429,
      date: '2022-10-28T00:00:00.000Z',
      home_team: {
        id: 18,
        abbreviation: 'MIN',
        city: 'Minnesota',
        conference: 'West',
        division: 'Northwest',
        full_name: 'Minnesota Timberwolves',
        name: 'Timberwolves',
      },
      home_team_score: 0,
      period: 0,
      postseason: false,
      season: 2022,
      status: '8:00 PM ET',
      time: '',
      visitor_team: {
        id: 14,
        abbreviation: 'LAL',
        city: 'Los Angeles',
        conference: 'West',
        division: 'Pacific',
        full_name: 'Los Angeles Lakers',
        name: 'Lakers',
      },
      visitor_team_score: 0,
    },
    {
      id: 857440,
      date: '2022-10-29T00:00:00.000Z',
      home_team: {
        id: 7,
        abbreviation: 'DAL',
        city: 'Dallas',
        conference: 'West',
        division: 'Southwest',
        full_name: 'Dallas Mavericks',
        name: 'Mavericks',
      },
      home_team_score: 0,
      period: 0,
      postseason: false,
      season: 2022,
      status: '9:00 PM ET',
      time: '',
      visitor_team: {
        id: 21,
        abbreviation: 'OKC',
        city: 'Oklahoma City',
        conference: 'West',
        division: 'Northwest',
        full_name: 'Oklahoma City Thunder',
        name: 'Thunder',
      },
      visitor_team_score: 0,
    },
  ],
  meta: {
    total_pages: 24,
    current_page: 1,
    next_page: 2,
    per_page: 50,
    total_count: 1161,
  },
}

jest.mock('@remix-run/node', () => ({
  fetch: mockFetch,
}))

describe.skip('getGames', () => {
  beforeEach(() => {
    mockFetch.mockClear()
  })

  it('should return list of games', async () => {
    // mockFetch.mockResolvedValue(mockResponse(mockGames))

    // const expectedResults = await getGames()

    // expect(expectedResults).toEqual(mapGamesData(mockGames.data))

    expect(true).toBeTruthy()
  })
})

jest.config.js

/** @type {import(@jest/types).Config.InitialOptions} */

module.exports = {
  collectCoverage: true,
  collectCoverageFrom: [
    '<rootDir>/src/**/*.{js,jsx,ts,tsx}',
    '!**/*.d.ts',
    '!**/entry.*.*',
    '!**/node_modules/**',
    '!**/root.*',
    '!**/routes/**',
    '!**/index.*',
  ],
  coverageDirectory: '<rootDir>/reports',

  coverageReporters: ['json', 'lcov', 'text'],

  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 50,
      statements: 50,
    },
  },

  moduleDirectories: ['node_modules', '<rootDir>/node_modules'],

  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],

  testEnvironment: 'jsdom',

  testPathIgnorePatterns: ['<rootDir>/node_modules/'],

  transform: {
    '^.+\\.[jt]sx?$': [
      'babel-jest',
      {
        presets: [
          '@babel/preset-env',
          ['@babel/preset-react', { runtime: 'automatic' }],
          '@babel/preset-typescript',
        ],
        plugins: ['@babel/plugin-transform-runtime'],
      },
    ],
  },
}

jest.setup.js

import '@testing-library/jest-dom/extend-expect'

import { installGlobals } from '@remix-run/node'
import { configure } from '@testing-library/react'

configure({ testIdAttribute: 'data-test' })

installGlobals()

错误截图

Jest错误


解决方案

这个错误是因为babel-jest错误转译了@testing-library/jest-dom扩展的expect方法,导致其内部结构被破坏。可以通过以下步骤解决:

  1. 添加transformIgnorePatterns配置
    在jest.config.js中新增该配置,排除不需要转译的测试相关依赖包:
module.exports = {
  // ... 其他配置
  transformIgnorePatterns: [
    '/node_modules/(?!@testing-library|@remix-run/node|@jest)'
  ],
}

这些包本身已经是编译好的代码,不需要再用babel转译,否则会破坏expect的扩展方法。

  1. 检查babel配置的preset-env目标
    确保@babel/preset-env的targets适配jest运行环境,可以在babel配置中添加:
{
  "presets": [
    ["@babel/preset-env", { "targets": { "node": "current" } }],
    // ... 其他presets
  ]
}
  1. 统一依赖版本
    检查jest、babel-jest、@babel/preset-env、@testing-library/jest-dom的版本是否兼容,建议升级到最新稳定版,避免版本冲突导致的异常。

  2. 调整初始化文件导入顺序
    将@testing-library/jest-dom/extend-expect的导入放在最顶部,确保它在其他代码之前扩展expect:

import '@testing-library/jest-dom/extend-expect'
// 其他导入...

内容的提问来源于stack exchange,提问作者Darrell Washington

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 10:25:21