You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue 2+Jest单元测试遇import语法错误,求排查方案

问题

使用Jest进行Vue2单元测试时,遇到报错:

SyntaxError: Cannot use import statement outside a module
报错栈:
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)

已尝试以下操作但未解决:

  • 在package.json中添加type:module
  • 在jest.config.js配置transformIgnorePatterns
  • 给组件的script标签添加module属性

当前环境基于Vue2跟进课程学习,相关代码如下:

package.json

{
  "name": "jest-test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "axios": "^1.2.3",
    "core-js": "^3.6.5",
    "vue": "^2.6.11",
    "vuex": "^3.4.0"
  },
  "devDependencies": {
    "@babel/preset-env": "^7.20.2",
    "@vue/cli-plugin-babel": "^4.1.2",
    "@vue/cli-plugin-eslint": "^4.1.2",
    "@vue/cli-plugin-unit-jest": "^4.1.2",
    "@vue/cli-plugin-vuex": "^4.1.2",
    "@vue/cli-service": "^4.1.2",
    "@vue/eslint-config-standard": "^5.1.2",
    "@vue/test-utils": "^1.0.3",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^6.2.2",
    "node-sass": "^4.12.0",
    "sass-loader": "^8.0.2",
    "vue-template-compiler": "^2.6.11"
  }
}

待测试组件(TodoTitle.vue)

<template>
  <div>
    {{ todo.title }}
  </div>
</template>
<script>
import axios from "axios";
export default {
  data() {
    return {
      todo: {},
    };
  },
  created() {
    this.fetchTodo();
  },
  methods: {
    async fetchTodo() {
      const { data } = await axios.get(
        "https://jsonplaceholder.typicode.com/todos/1"
      );
      this.todo = data;
    },
  },
};
</script>

测试代码(TodoTitle.spec.js)

import { shallowMount } from "@vue/test-utils";
import TodoTitle from "@/components/TodoTitle";

describe("TodoTitle Component", () => {
test("rendering", () => {
const wrapper = shallowMount(TodoTitle);
console.log(wrapper);
expect(wrapper.text()).toBe("");
});
});

解决方案

问题根源:axios@1.x版本默认输出ES模块,而Jest默认不会转译node_modules目录下的文件,导致无法识别import语句。结合Vue CLI 4的Jest配置,按以下步骤修复:

1. 移除package.json中的type:module

Vue CLI 4的Jest配置基于CommonJS规范,添加type:module会导致模块加载冲突,直接删除该配置项。

2. 配置jest.config.js

在项目根目录创建或修改jest.config.js,确保转译规则覆盖axios:

module.exports = {
  preset: '@vue/cli-plugin-unit-jest',
  transformIgnorePatterns: [
    // 排除node_modules中除axios外的其他模块,确保axios被转译
    '/node_modules/(?!axios)/'
  ],
  transform: {
    '^.+\\.vue$': 'vue-jest',
    '^.+\\.js$': 'babel-jest'
  }
}

3. 配置babel.config.js

确保Babel预设正确适配Jest环境,修改babel.config.js:

module.exports = {
  presets: [
    ['@vue/cli-plugin-babel/preset', {
      targets: {
        node: 'current'
      }
    }]
  ]
}

4. 重新运行测试

执行npm run test:unit,此时Jest会转译axios模块,import语句可以正常识别。

额外优化:Mock axios避免网络请求

测试时建议Mock axios的请求,避免实际网络调用影响测试结果,修改测试代码:

import { shallowMount } from "@vue/test-utils";
import TodoTitle from "@/components/TodoTitle";
import axios from "axios";

// Mock axios.get
jest.mock('axios', () => ({
  get: jest.fn().mockResolvedValue({
    data: { title: 'Mocked Todo Title' }
  })
}));

describe("TodoTitle Component", () => {
  test("rendering", async () => {
    const wrapper = shallowMount(TodoTitle);
    // 等待异步请求完成
    await wrapper.vm.$nextTick();
    expect(wrapper.text()).toBe("Mocked Todo Title");
  });
});

内容的提问来源于stack exchange,提问作者YESSS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 12:00:58