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

How can I get the class name of the drop destination with react-dnd?

Imagine having this component that serves as a drop target module. import { useDrop } from 'react-dnd'; import './css/DraggableGameSlot.css'; type DraggableGameSlotProps = { className: string, text: string } function Draggable ...

Does anyone else have trouble with the Smtp settings and connection on Servage.net? It's driving me crazy, I can't figure it out!

Whenever I attempt to connect to send a servage SMTP, it gives me this error message: SMTP connect() failed. I have tried using the following settings: include('res/mailer/class.phpmailer.php'); $mail->SMTPDebug = 2; include('res/mai ...

Explore the flexibility of npm by installing and utilizing various versions of a specific package

Is it possible to install and utilize different versions of packages in npm? Installation can be done as follows: npm install -g <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1d6d7c7e767c7a78737c70785d2f3325">[email p ...

Expanding the size of an array list item in React

I have an array containing various currencies: const currencies =['USD','EUR','AUD','CNY','AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'A ...

Display only the relevant data in a v-for loop

I'm struggling with the code snippet below: <template> <div> <div v-for="title in titles"> <h1>{{ title }}</h1> <a @click="showSub">Click Here</a> <div v-if=& ...

Setting up HMR for a Vue.js app can be a bit tricky, especially when trying to run it locally

1. The Caddy version I am using (caddy -version): v2.0.0-beta.13 h1:QL0JAepFvLVtOatABqniuDRQ4HmtvWuuSWZW24qVVtk= 2. How I execute Caddy: a. Environment details: I have the caddy server static binary running on macOS Mojave - 10.14.6, and added the bina ...

Incorporate JavaScript code into an Angular UI-Router view

I can't seem to find an answer to this question anywhere, so I'm hoping someone here can help me out. In my AngularJS app, I am using ui-router to load multiple views into the same <ui-view> element. I am trying to implement Jquery UI&apos ...

React-Troubleshooting list items and keys: A comprehensive guide to resolving common issues

I'm facing a challenge with generating unique key ID's for my list items. Even though I thought I had a good understanding of how unique keys function, it seems that I am mistaken. In the code snippet below, using key={index} or key={item} is no ...

Utilize route parameters in the nested subRoutes object in Vue.js to easily access data specific to

Is there a way to directly access the route params within the route objects? I need to load different components based on the route object. router.map({ '/dashboard/*': { component: Home }, '/dashboard/:module': { compone ...

Transforming jQuery into Angular - Press Button to update choices in Dropdown List

I am looking to integrate some AngularJS features into a website that currently utilizes jQuery. Here is the issue I am facing: With jQuery, clicking a button triggers a dropdown item change. Please refer to the jsfiddle below for an example: $('# ...

when the submit button is clicked, verify whether the input field is empty

I have exhausted all my options and nothing seems to work. All I want is for the following functionality to be implemented: When a submit button is clicked -> check if a text field is empty -> if it is, display an error alert and prevent advancing t ...

The Joomla jCE popup feature is not functioning properly when used with AJAX content

Currently, I am using Joomla for my project. One of the features I have implemented is Ajax to display a specific section on a page. Within this Ajax-loaded section, there is a JCE popup link included in the code: <a href="some link" class="jcepopup no ...

431 - (Excessive Request Header Size)

First time asking for help, please take that into consideration What I've tried: I cleared my Google Chrome cache and cookies, attempted incognito mode, updated to the latest node version, but still encountering the same error. Error message in Chro ...

Is there a way to identify when a Tween.js animation has completed?

Is there a completed or finished event available when using this code for animating the camera in a scene with tween.js? tween : function (target){ var position = camera.position; var tween = new TWEEN.Tween(p ...

Preventing Vue.js SPA from accessing cached version when JWT expires: the solution

I'm encountering an issue with my Vue.js / Express application that I can't seem to resolve. Here's how the process unfolds: An unauthenticated user logs into the app and is presented with the login page. Once successfully authenticated, t ...

Why does my event dispatch only run once upon form submission in Svelte JS?

My code successfully fetches data and puts it in a card when new data is added to the input. However, the issue arises when more than one data entry is made - although the data gets added to the database, it does not reflect in the data list. Can anyone he ...

Is it necessary for me to be concerned with clearing out sizable objects in Node.js, or should I trust the garbage collector to handle

Recently, I encountered a memory issue with my node.js API while hosting it on Heroku's free version with only 512MB RAM. As the traffic increased over the weekend, I started receiving memory errors from Heroku due to exceeding limits. Despite searchi ...

Encountering error code 2064 without any clear explanation in sight

Hey, I'm currently facing an issue while uploading values to a MySQL table from Node.js. The error 1064 keeps popping up, indicating that the query is badly formatted. However, I can't seem to pinpoint the exact problem. Here's the query in ...

Is there a way to prevent my token from being exposed when making an AJAX call?

When working on my HTML file, I encountered an issue with a Python Django URL integration where I need to pass a token to retrieve certain information. However, the problem is that my token is exposed when inspecting the page source in the HTML document. ...

Clicking on the initial link will in turn prompt clicks on the subsequent links

Can you please provide instructions on how to correctly simulate a click on the remaining links if a click is made on the first link? jQuery('a.one_num').click(function() { jQuery('a.two_num').click(); jQuery('a.three_num&ap ...