Reputation: 575
I have a vue application with single file components and i want to add unit tests to test the components. I'm trying to use jest like described here but i keep getting the error "Jest encountered an unexpected token" with the following details:
/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)
After some research (e.g. from here) I gather that this is probably due to jest expecting a .js file, but the .vue single file components have html, javascript and css in them, usually dealt with by webpack and vue-loader. I've tried to follow jest configurations from various tutorials to make jest use vue-jest to transform .vue files, but the error persists. This is my package.json file (unnecessary parts removed):
{
"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"
]
}
}
Any idea what might be wrong, or some tips on how to debug this?
EDIT: I have looked into this question and I don't believe the answer there would solve my problem since what I am trying to import is a .vue file and not an .html file.
EDIT 2: I have a feeling that jest is somehow just not picking up the transforms, because removing them from package.json doesn't change anything.
EDIT 3: No, jest is correctly using vue-jest for transforming. If I uninstall vue-jest and try running the test again, jest complains that vue-jest is missing.
Upvotes: 7
Views: 15255
Reputation: 3143
You need to install vue-jest (https://github.com/vuejs/vue-jest) with
npm install -D @vue/vue3-jest
Here are the available versions and their corresponding vue and jest versions
Vue version | Jest Version | Package |
---|---|---|
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 |
Then, you'll just have to update your jest configuration (in jest.config.ts
for example) and add a transform section
"transform": {
"^.+\\.vue$": "@vue/vue3-jest"
}
Warning: be sure to update the npm install
and the jest.config.ts
with the vue-jest package that match your need!
Upvotes: 0
Reputation: 1290
I faced same issues tried many solution but none of them work ..below is following workaround in my case
Check package json has following dev dependency entries and jest configurations
"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/"
}
Check babel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
],
};
check jest.config.js
module.exports = {
preset: '@vue/cli-plugin-unit-jest',
};
Upvotes: 0
Reputation: 41
What worked for me was changing the transform of the vue-jest
to what is shown in the documentation.
https://github.com/vuejs/vue-jest
so try using "^.+\\.vue$": "vue-jest"
instead of "^[^.]+.vue$": "vue-jest"
full config might look like this
{
"jest": {
"moduleFileExtensions": ["js", "json", "vue"],
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.vue$": "vue-jest"
}
}
}
Upvotes: 2
Reputation: 85
Met same issuesome time ago. What i found.
The problem was in the short note of template v-slot
template(v-slot:body)
It works to compile, but Jest throws an error
Jest encountered an unexpected 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.
There was two ways i fount to solve this:
globals: {
'vue-jest': {
pug: {
doctype: 'html',
},
},
},
template(v-slot:body="")
Upvotes: 3
Reputation: 575
The solution to my problem turns out to be a bit anti-climatic.
The problem was that my regexp string to recognize .vue files was wrong and didn't pick up my MyRecipe.vue file. Therefore, vue-jest wasn't used to transform it for jest to interpret, hence the trouble understanding that the file in question started with a very non-js line; <template>
. The regexp that works is ^[^.]+.vue$
, so the transform
section of my package.json file becomes
{
// ...
"jest": {
// ...
"transform": {
"^[^.]+.vue$": "vue-jest",
"^.+\\.js$": "babel-jest"
},
// ...
}
}
Upvotes: 5