While conducting tests on a Vue single file component, Jest came across an unforeseen token

I need help with setting up unit tests for my Vue application that uses single file components. I've been trying to use Jest as mentioned in this guide, but encountered an error "Jest encountered an unexpected token" along with the details below:

/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 researching, such as from here, it appears that Jest might be expecting a .js file while the .vue single file components contain HTML, JavaScript, and CSS which are typically handled by webpack and vue-loader. Despite following various tutorials to configure Jest to transform .vue files using vue-jest, the error persists. Here is a snippet of 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"
    ]
  }
}

If you have any insights on what could be wrong or tips on troubleshooting this issue, please share.

EDIT: I've checked out this question and don't think the solution there applies to importing .vue files instead of .html files.

EDIT 2: It seems like Jest is not recognizing the transforms properly, as removing them from package.json doesn't make a difference.

EDIT 3: Jest does seem to be utilizing vue-jest for transformation correctly. When I uninstall vue-jest and run the test again, Jest complains about vue-jest being missing.

Answer №1

I was faced with an unexpected resolution to my issue.

The root cause of the problem turned out to be a simple mistake in my regular expression string for identifying .vue files, causing it to overlook MyRecipe.vue file. Consequently, vue-jest didn't carry out the transformation needed for jest to comprehend the file properly, resulting in confusion due to the initial line not being JavaScript related; <template>. The correct regexp is ^[^.]+.vue$, so I updated the transform section in my package.json file as follows:


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

Answer №2

I encountered similar issues in the past and here is what I discovered:

The problem was due to a short notation in the template v-slot

template(v-slot:body)

Although it compiled, Jest threw 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.

I found two ways to resolve this issue:

  1. Editing my jest.config.js as shown below:
globals: {
  'vue-jest': {
    pug: {
      doctype: 'html',
    },
  },
},
  1. Writing a full notation like this
    template(v-slot:body="")

Answer №3

By making a simple adjustment to the transform property in my vue-jest setup as outlined in the official documentation, I was able to resolve the issue that had been plaguing me.

Instead of using

"^[^.]+.vue$": "vue-jest"
, consider using
"^.+\\.vue$": "vue-jest"
. A complete configuration example may include:

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

Answer №4

After encountering the same issues and trying numerous solutions without success, I finally found a workaround that worked for me:

  1. First, ensure that your package.json file contains the necessary dev dependencies 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/"
     }
    
  1. Next, make sure to review your babel.config.js file:

      module.exports = {
        presets: [
        '@vue/cli-plugin-babel/preset',
      ],
     };
    
  2. Finally, double-check your jest.config.js file :

      module.exports = {
       preset: '@vue/cli-plugin-unit-jest',
      };
    

Answer №5

To successfully set up vue-jest (https://github.com/vuejs/vue-jest), you will need to execute the following command:

npm install -D @vue/vue3-jest

Refer to the table below for the compatible versions of vue and jest along with their respective packages.

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

After installation, remember to update your jest configuration (e.g., in jest.config.ts) by including a transform section.

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

Note: Make sure to align your npm install and jest.config.ts settings with the suitable vue-jest package!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

D3 Chart: What is the best way to insert images into a node?

Within the jsFiddle demo provided in this query, there is code displayed. I am curious about how I can assign images to each node. var graph = { "nodes":[ {"name":"1","rating":90,"id":2951}, ] } You can access my jsFiddle Demo through this ...

Seeking materials for WebDriverJs?

It has come to my attention that there are some valuable resources available: http://docs.seleniumhq.org/docs/03_webdriver.jsp https://code.google.com/p/selenium/wiki/WebDriverJs However, I am curious if there exists a comprehensive website that prese ...

What is the best way to set up jest on my system?

Having some difficulties installing jest using the following command: npm i --global jest and encountering these messages: npm WARN deprecated <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="17657264787b61723a62657b57273925392 ...

use dotenv in your Build Folder

Is it possible to have my .env file in my React JS project move to the build folder when I run NPM build command? If so, how can this be achieved? If not, what would be the alternative solution? I attempted using "build": "cp .env.template ...

Validation is performed on the Bootstrap modal form, ensuring that the modal is only loaded after the

In order to provide a better understanding of my website's file structure, I would like to give an overview. The index.php file dynamically adds many pages to my website. Here is the code from index.php: <?php include ('pages/tillBody.php ...

Creating a realistic typewriter effect by incorporating Code Block as the input

I am looking to add a special touch to my website by showcasing a code segment with the Typewriter effect. I want this code block not only displayed but also "typed" out when the page loads. Unfortunately, I have been unable to find a suitable solution s ...

How can I fetch data from SQL using JavaScript based on a specific value in PHP?

My application is built using the Yii2 framework. Within my application, there is a view.php file that consists of an element and a button. The element, <div id="userId">, contains the user's login ID, and I aim to use the button to re ...

Using the `preventDefault` method within an `onclick` function nested inside another `onclick

I am currently working on an example in react.js <Card onClick="(e)=>{e.preventDefault(); goPage()}"> <Card.body> <Media> <img width={64} height={64} className="mr-3" ...

How to properly format JSON responses in Node.js or Express

I came across a question on Proper way to return JSON using node or Express and copied it for reference. I am looking for the response in a specific format. This is the sample format for the response API: { "success":true, "code":200, "message":"Ok", "da ...

Using a navigation bar as a structural component in React

I have a new app in development that features a search bar on every page as part of the layout. When a user conducts a search, the results are displayed and they can click on a result to view more details in a separate component. My main question is regar ...

Using Vue to dynamically upload multiple files simultaneously

Although this question has been asked frequently, most of the answers do not address a key issue - how to upload multiple images while knowing which image belongs to which data. Attempting to bind v-model to input file doesn't work as expected, and ev ...

What is the best way to implement a modal that can toggle dark mode using the Konami code, with the added functionality of a close button?

Recently, I attempted to create a Modal window that would activate when the Konami code (↑↑↓↓←→←→BA) is typed. As someone new to JavaScript, I'm still learning and open to feedback. While I have the coding part figured out, I need assi ...

Leveraging AngularJS to send a post request to the server through the $http

Can't seem to find a solution to my Angular issue, despite searching for it extensively? After starting to learn Angular recently, I've put together the following code based on various online resources. Here's the HTML: <div data-ng-ap ...

Guide to utilizing a shared route function across various routes in express.js

Is there a way to handle the scenario where I need both www.example.com/12345/xxxxx and www.example.com/xxxxx to trigger the same function in my application using Express? app.get('/:someVar/xxxxx', function(req, res) { /* etc */ }); I can acce ...

What is the best way to successfully send an object through AJAX once all its updates are completed?

I am experiencing an issue with my JavaScript code within an event: var userData = tableWidget.grid('userData'); console.log(tableWidget.grid('userData')); $.ajax({ "url": "../../server/query.aspx?tableEvent=reordercolumns&tabl ...

`Set-cookie` isn't effective in dist compilation produced by the `npm run build` command

Currently, my vue frontend server utilizes cookies to manage the login state in conjunction with a basic backend server. The issue arises when set-cookie functions properly in production mode while running npm run serve. However, upon bundling the project ...

Leveraging $this in conjunction with a jQuery plugin

I'm experimenting with a code snippet to reverse the even text in an unordered list: $(document).ready(function () { $.fn.reverseText = function () { var x = this.text(); var y = ""; for (var i = x.length - 1; i >= 0; ...

Is there a way for me to iterate through an array of objects within a Redux reducer file in order to remove a specific user?

I am facing a challenge while trying to remove a user in redux. The issue arises when I use the map function in the reducer.js file and encounter a 'state.users.map is not a function' error. Upon investigation, I realized that the array consists ...

Is there a way to streamline the process of connecting multiple ajax requests automatically?

After reviewing the lower portion of my function, I realized that I need to repeat info(url_part1 + next + url_part2, function(next) { multiple times. Is there a more efficient way to accomplish this task, perhaps utilizing some type of loop? I have been b ...

What is the best way to share information among Vue3 single file component instances?

I am seeking a way to have certain data in my single file component shared among all instances on the page, similar to how static variables work in PHP/C. To achieve this, I understand that in single file components, we declare data as a function like so: ...