You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Vue+TypeScript项目Jest单元测试报错:TypeError: Object prototype may only be an Object or null: undefined

解决Vue+TypeScript项目Jest单元测试中的TypeError: Object prototype may only be an Object or null: undefined错误

我之前在Vue + TypeScript项目里用Jest做单元测试时也碰到过一模一样的错误,折腾了好一阵才找到原因,大概率是Jest处理Vue组件或TypeScript依赖时的原型链解析问题,下面是我排查和解决的几个方向,你可以逐一试试:

1. 检查Jest配置的转换规则与文件扩展名

首先要确保Jest能正确识别并转换Vue和TS文件,很多时候这个错误是因为Vue文件没被vue-jest处理,或者TS文件的转换规则不匹配。

打开你的jest.config.js(或jest.config.ts),确认配置里包含以下内容:

module.exports = {
  preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
  transform: {
    // 用vue-jest处理Vue单文件组件
    '^.+\\.vue$': 'vue-jest',
    // 用ts-jest处理TS/TSX文件
    '^.+\\.tsx?$': 'ts-jest'
  },
  // 确保Jest能识别这些文件类型
  moduleFileExtensions: ['vue', 'js', 'ts', 'json', 'jsx', 'tsx']
};

另外要注意版本兼容性:如果是Vue 3项目,要使用vue-jest@next;Vue 2项目则对应vue-jest@4.x版本,版本不匹配很容易触发原型链错误。

2. 排查组件的继承/混入(Mixin)问题

如果你的组件继承了某个基类组件,或者使用了Mixin,很可能是这个依赖在测试环境下没有被正确加载,导致原型链指向了undefined

比如组件里有这样的代码:

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
// 假设这个基类组件在测试时未被正确解析
import BaseCard from './BaseCard.vue';

@Component({ extends: BaseCard })
export default class MyCard extends Vue {}
</script>

解决方法:

  • 确认基类组件的路径正确,且在测试环境中能被Jest找到;
  • 如果基类组件有复杂依赖,可以在测试文件中手动模拟它:
    import { shallowMount } from '@vue/test-utils';
    import MyCard from '@/components/MyCard.vue';
    
    // 模拟基类组件
    jest.mock('@/components/BaseCard.vue', () => ({
      name: 'BaseCard',
      render: (h: any) => h('div')
    }));
    
    describe('MyCard', () => {
      it('renders correctly', () => {
        const wrapper = shallowMount(MyCard);
        expect(wrapper.exists()).toBe(true);
      });
    });
    

3. 检查测试文件的组件挂载方式

使用@vue/test-utils挂载组件时,环境隔离不到位也可能触发原型链错误。试试用createLocalVue来创建独立的Vue实例,避免全局污染:

import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import MyComponent from '@/components/MyComponent.vue';

const localVue = createLocalVue();

describe('MyComponent', () => {
  it('renders properly', () => {
    const wrapper = shallowMount(MyComponent, { localVue });
    expect(wrapper.find('.component-content').exists()).toBe(true);
  });
});

如果组件依赖了Vue插件(比如Vuex、VueRouter),也要在localVue上注册这些插件,避免挂载时出现原型问题。

4. 对齐TypeScript与Jest的配置

TypeScript的编译配置和Jest的运行环境不兼容也会导致这类错误。打开tsconfig.json,确认以下关键配置:

{
  "compilerOptions": {
    "target": "ES6", // 不要设为过低的版本,比如ES3
    "module": "CommonJS", // Jest运行在Node环境,需要CommonJS模块
    "strict": true,
    "moduleResolution": "node",
    "esModuleInterop": true, // 解决CommonJS与ES模块的兼容性问题
    "skipLibCheck": true // 跳过第三方库的类型检查,避免干扰
  }
}

5. 清除缓存并重装依赖

有时候缓存会导致各种奇怪的依赖解析问题,试试以下步骤:

  1. 删除node_modules和锁文件:
    rm -rf node_modules package-lock.json # 用yarn的话删yarn.lock
    
  2. 重新安装依赖:
    npm install
    
  3. 清除Jest的缓存:
    jest --clearCache
    

如果以上方法都没能解决问题,建议把你的组件代码、测试代码以及完整的Jest/TS配置贴出来,这样能更精准地定位问题。

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

火山引擎 最新活动