Jest在测试Vue单文件组件时遇到了意外的标记。

7
我有一个Vue应用程序,使用单文件组件,并且我想添加单元测试来测试这些组件。 我正在尝试像这里描述的那样使用Jest,但是我一直遇到错误“Jest遇到意外的标记”,具体细节如下:
/some_path/MyRecipe.vue:1
<template>
^

SyntaxError: Unexpected token <

  1 | import { shallowMount } from "@vue/test-utils"
> 2 | import MyRecipe from "../src/components/MyRecipe.vue"
    | ^
  3 | 
  4 | describe('MyRecipe', () => {
  5 |   test('is a Vue instance', () => {

  at Runtime._execModule (node_modules/jest-runtime/build/index.js:1166:56)
  at Object.<anonymous> (__tests__/MyRecipe.test.js:2:1)

经过一些研究(例如从这里),我了解到这可能是由于jest期望.js文件,但.vue单文件组件中包含了HTML、JavaScript和CSS,通常由webpack和vue-loader处理。我尝试遵循各种教程中的jest配置,使用vue-jest转换.vue文件,但错误仍然存在。这是我的package.json文件(删除了不必要的部分):

{
  "name": "all-recipes ",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    // ...
    "test": "jest"
  },
  "dependencies": {
    // ...
    "core-js": "^3.4.3",
    "vue": "^2.6.10"
    // ...
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.1.0",
    "@vue/cli-plugin-eslint": "^4.1.0",
    "@vue/cli-service": "^4.1.0",
    "@vue/test-utils": "^1.0.3",
    "babel-core": "^7.0.0-bridge.0",
    "babel-eslint": "^10.0.3",
    "babel-jest": "^26.0.1",
    // ...
    "jest": "^26.0.1",
    "jest-serializer-vue": "^2.0.2",
    "vue-jest": "^3.0.5",
    "vue-template-compiler": "^2.6.10",
    "vue-test-utils": "^1.0.0-beta.11"
  },
  // ...
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "vue"
    ],
    "transform": {
      ".*\\.,(vue)$": "vue-jest",
      "^.+\\.js$": "babel-jest"
    },
    "snapshotSerializers": [
      "jest-serializer-vue"
    ]
  }
}

有没有什么想法是出了什么问题,或者有什么调试技巧可以提供?
编辑:我查看了这个问题,我不认为那里的答案会解决我的问题,因为我想要导入的是一个 .vue 文件,而不是一个 .html 文件。
编辑2:我有一种感觉,jest 似乎只是没有检测到转换器,因为从 package.json 中删除它们并没有改变任何内容。
编辑3:不,jest 正确地使用 vue-jest 进行转换。如果我卸载 vue-jest 并再次运行测试,jest 就会抱怨缺少 vue-jest。

这个回答解决了你的问题吗?Jest + Vue - SyntaxError: Unexpected token < - Józef Podlecki
很遗憾,@JózefPodlecki。在你提到的问题中,错误出现在尝试导入一个 .html 文件时。我不认为创建一个自定义的 html-loader 会解决这个问题,因为 .vue 文件还包含 javascript 和 css。 - Nanna
1
你为什么要使用".*\\.,(vue)$": "<rootDir>/node_modules/vue-jest"而不是文档中所述的简单形式".*\\.(vue)$": "vue-jest" - feihcsim
这是我跟随其他教程后得出的建议,最初尝试了 "vue-jest" 之后尝试过它。现在我刚刚试着改回去,以防在此期间发生了一些变化,但不幸的是那样做没有起到作用。 - Nanna
1
为了进行故障排除,我会生成一个新的Vue CLI项目,包括Jest(它没有这个问题),并从那里找出差异(例如,将其与您的项目进行比较)。 - tony19
5个回答

5

我的问题的解决方案有点令人失望。

问题在于我对于识别.vue文件的正则表达式字符串是错误的,无法识别到MyRecipe.vue文件。因此,vue-jest没有被用来对其进行转换,以便jest去解释它,这就导致了理解相关文件以非js行; <template>开头时遇到了麻烦。工作的正则表达式是^[^.]+.vue$,因此我的package.json文件中的transform部分变成

{
  // ...
  "jest": {
    // ...
    "transform": {
      "^[^.]+.vue$": "vue-jest",
      "^.+\\.js$": "babel-jest"
    },
    // ...
  }
}

3

我之前遇到过同样的问题,发现是模板 v-slot 中的短注释有问题。

template(v-slot:body)

虽然这个语法可以正常编译,但 Jest 会抛出错误:

Jest 遇到了一个意外的标记(token)。

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

Here's what you can do:
  To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
  If you need a custom transformation specify a "transform" option in your config.
  If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

我找到了两种解决方案:

  1. 编辑我的jest.config.js,像这样:
globals: {
  'vue-jest': {
    pug: {
      doctype: 'html',
    },
  },
},
  1. 写一个类似这样的完整的注释:template(v-slot:body="")

2

对我有用的是将vue-jest的转换更改为文档中显示的内容。 https://github.com/vuejs/vue-jest

因此,请尝试使用"^.+\\.vue$": "vue-jest"而不是"^[^.]+.vue$": "vue-jest" 完整配置可能如下所示

{
  "jest": {
    "moduleFileExtensions": ["js", "json", "vue"],
    "transform": {
      "^.+\\.js$": "babel-jest",
      "^.+\\.vue$": "vue-jest"
     }
   }
}

0

我遇到了同样的问题,尝试了很多解决方案,但都没有奏效...以下是我这种情况下的解决方法

  1. 检查 package.json 文件是否包含以下开发依赖项和 jest 配置

     "devDependencies": {
         "babel-jest": "^23.6.0",
         "@vue/cli-plugin-babel": "~4.5.0",
         "@vue/cli-plugin-eslint": "~4.5.0",
         "@vue/cli-plugin-unit-jest": "~4.5.0",
         "@vue/cli-service": "~4.5.0",
         "@vue/eslint-config-airbnb": "^5.0.2",
         "@vue/test-utils": "^1.0.3",
         "babel-eslint": "^10.1.0",
         "eslint": "^6.7.2",
         "eslint-plugin-import": "^2.20.2",
         "eslint-plugin-vue": "^6.2.2",
           },
    
      "jest": {
         "moduleFileExtensions": [
         "js",
         "jsx",
         "json",
         "vue"
        ],
      "transform": {
        "^.+\\.vue$": "vue-jest"
        },
     "moduleNameMapper": {
       "^@/(.*)$": "<rootDir>/src/$1"
      },
    "snapshotSerializers": [
       "jest-serializer-vue"
     ],
    "testMatch": [
       "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*. 
    (js|jsx|ts|tsx)"
     ],
     "testURL": "http://localhost/"
     }
    
2. 检查 babel.config.js 文件
``` module.exports = { presets: [ '@vue/cli-plugin-babel/preset', ], }; ```
3. 检查 jest.config.js 文件
``` module.exports = { preset: '@vue/cli-plugin-unit-jest', }; ```

0

您需要安装vue-jesthttps://github.com/vuejs/vue-jest

npm install -D @vue/vue3-jest

以下是可用版本及其对应的Vue和Jest版本

Vue版本 Jest版本 软件包
Vue 2 Jest <= 26 vue-jest@4
Vue 3 Jest <= 26 vue-jest@5
Vue 2 Jest 27 @vue/vue2-jest
Vue 3 Jest 27 @vue/vue3-jest

然后,您只需更新Jest配置(例如在jest.config.ts中)并添加一个transform section

"transform": {
    "^.+\\.vue$": "@vue/vue3-jest"
}

警告:请确保使用与您需求相匹配的vue-jest包更新npm installjest.config.ts


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接