用 TypeScript 开玩笑:TypeError: environment.teardown 不是函数

Posted

技术标签:

【中文标题】用 TypeScript 开玩笑:TypeError: environment.teardown 不是函数【英文标题】:Jest with TypeScript: TypeError: environment.teardown is not a function 【发布时间】:2019-01-19 10:52:23 【问题描述】:

当我尝试使用 Jest 运行测试时出现此错误:

 FAIL  src/__tests__/jokeGenerator.test.tsx
  ● Test suite failed to run

    TypeError: environment.teardown is not a function

      at node_modules/jest-runner/build/run_test.js:230:25

我在这里遇到了一个可能的解决方案:How to solve TypeError: environment.teardown is not a function

但是在按照建议进行操作后:删除我的 yarn.lock 文件、node_modules 文件夹,从我的 package.json 中删除 Jest,然后使用 yarn 重新安装所有内容——我遇到了一个新问题:

  ● Test suite failed to run

    TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string

      at assertPath (path.js:39:11)
      at Object.relative (path.js:1173:5)
      at Object.getCacheKey (node_modules/ts-jest/dist/utils/get-cache-key.js:15:16)

我有一种预感,之前的解决方案对其他人有效的原因是因为他们使用了create-react-app,然后在其旁边安装了一个有冲突的 jest 版本。如果是这样,那么上述解决方案不适用于我的问题,因为我没有使用create-react-app

所以我重新安装了 Jest 和 @types/jest,现在遇到了同样的初始问题...

这是我的 webpack 配置:

module.exports = 
  entry: './src/index.tsx',
  devServer: 
    contentBase: __dirname + '/dist/',
  ,
  module : 
    rules: [
      
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: 
          loader: 'ts-loader'
        
      ,
      
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          'style-loader',
          
            loader: 'typings-for-css-modules-loader?modules?named',
            options: 
              modules: true,
              namedExport: true
            
          
        ]
      
    ]
  

这是我的 package.json:


  "name": "practice-testing",
  "private": true,
  "version": "1.0.0",
  "description": "",
  "scripts": 
    "start": "webpack-dev-server --mode development --open --hot",
    "build": "webpack --mode production",
    "test": "jest"
  ,
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": 
    "@types/jest": "^23.3.1",
    "@types/react": "^16.4.9",
    "@types/react-dom": "^16.0.7",
    "babel-core": "^6.26.3",
    "babel-jest": "^23.4.2",
    "css-loader": "^1.0.0",
    "css-modules": "^0.3.0",
    "jest": "^23.5.0",
    "react-testing-library": "^5.0.0",
    "style-loader": "^0.22.1",
    "ts-jest": "^23.1.3",
    "ts-loader": "^4.4.2",
    "typescript": "^3.0.1",
    "typings-for-css-modules-loader": "^1.7.0",
    "webpack": "^4.16.5",
    "webpack-cli": "^3.1.0",
    "webpack-dev-server": "^3.1.5"
  ,
  "dependencies": 
    "react": "^16.4.2",
    "react-dom": "^16.4.2"
  ,
  "jest": 
    "testEnvironment": "node"
  

这是我开玩笑的配置:

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

最后,这是我的 tsconfig:


    "compilerOptions": 
        "module": "commonjs",
        "target": "es5",
        "jsx": "react",
        "noImplicitAny": true,
        "removeComments": true,
        "preserveConstEnums": true,
        "sourceMap": true,
    ,
    "include": [
        "./src/**/*",
    ],
    "exclude": [
        "node_modules",
    ]

【问题讨论】:

【参考方案1】:

TLDR

此错误通常意味着在node_modules 的根目录下安装了jest-environment-jsdom 和/或jest-environment-node,与用于运行测试的Jest 版本不兼容。

详情

这个很有趣。

问题是css-modules。它依赖于 jest@20.0.4(应该在它的 devDependencies 下)。

jest@20.0.4 最终安装了 jest-environment-jsdom@20.0.3jest-environment-node@20.0.3,它们最终位于 node_modules 的根目录中。

已安装jest@^23.5.0,它将jest-environment-jsdom@^23.4.0jest-environment-node@^23.4.0 安装在node_modules/jest 内的多个位置,但不是在node_modules 的根级别,因为存在20.0.3 版本。

当为Jest 指定testEnvironment 时,解析过程会查找环境。 The first place it tries is within the project 在这种情况下解析为 20.0.3 版本。

那些早期版本的测试环境不包含 Jest 的更高版本所需的所有内容,包括 teardown() 的定义。

package.json 中删除css-modules,删除您的package-lock.json 和/或yarn.locknode_modules 并运行npm install,这应该可以解决问题。

(注意css-modulesonly has 133 weekly downloads and no listed github site,我猜它是错误添加为依赖的,它与CSS Modules没有关联)

【讨论】:

伟大的收获!谢谢! 您可以通过cat node_modules/jest-environment-jsdom/package.json | grep _requiredBy -A3(在Linux 上)找出导致此问题的包,它将打印最初需要它的包。非常感谢这个答案,非常有帮助!【参考方案2】:

以防万一其他人在使用 yarn 工作区的项目中偶然发现这个问题,我通过 not hoisting jest 解决了同样的问题到项目根目录:

"workspaces": 
    "packages": [
        "packages/*"
    ],
    "nohoist": [
        "**/jest/**",
        "**/jest"
    ]
,

【讨论】:

以上是关于用 TypeScript 开玩笑:TypeError: environment.teardown 不是函数的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 typescript 用 jest 模拟 fs - 类型上不存在属性“mockReturnValue”

在 CI 中使用 typescript 路径开玩笑“找不到模块”

用玩笑模拟打字稿界面

如何允许 scss 开玩笑地对 typescript nextjs 进行单元测试?

用 Jest 测试 Typescript 接口

带有 Typescript 错误的玩笑:超时 - 在 jest.setTimeout.Timeout 指定的 5000 毫秒超时内未调用异步回调