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

使用Vue Test Utils测试Chart.js组件时触发window.matchMedia错误

解决Vue组件测试中window.matchMedia not found的错误

这个问题我之前在测试依赖Chartist的Vue组件时也碰到过,根源很清晰:Chartist在初始化时依赖浏览器的window.matchMedia API,但Mocha运行的Node.js/jsdom测试环境并没有提供这个原生API,而且抛出的错误是字符串形式,导致Mocha无法正确处理(它试图给错误对象添加uncaught属性,但字符串不是对象)。

下面是两步解决方法:

1. 模拟window.matchMedia API

在你的测试文件最顶部添加这段代码,给测试环境补全这个缺失的API:

// 为测试环境模拟window.matchMedia,适配Chartist的需求
global.window.matchMedia = global.window.matchMedia || function() {
  return {
    matches: false,
    addListener: () => {},
    removeListener: () => {}
  };
};

如果你的测试环境用的是新版jsdom,可能需要更完整的模拟(兼容新的事件监听API):

Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: function(query) {
    return {
      matches: false,
      media: query,
      onchange: null,
      addListener: () => {},
      removeListener: () => {},
      addEventListener: () => {},
      removeEventListener: () => {},
      dispatchEvent: () => {}
    };
  }
});

2. 处理组件中的异步Chartist加载

你的组件在mounted钩子中动态import Chartist,这意味着测试跑完后可能还有未完成的异步操作,会抛出未捕获的错误。你需要在测试中等待这些异步操作完成,或者提前导入Chartist避免动态加载的问题:

修改后的测试代码(用async/await处理异步)

import { expect } from 'chai';
import { mount } from '@vue/test-utils';
import ChartCard from '@/components/Cards/ChartCard.vue';

// 先模拟window.matchMedia
global.window.matchMedia = global.window.matchMedia || function() {
  return {
    matches: false,
    addListener: () => {},
    removeListener: () => {}
  };
};

describe('ChartCard.vue', () => {
  it('Has a title', async () => {
    const wrapper = mount(ChartCard);
    wrapper.setProps({title: 'test title'});
    // 等待DOM更新和Chartist加载初始化完成
    await wrapper.vm.$nextTick();
    // 额外等待异步import完成,可选
    await new Promise(resolve => setTimeout(resolve, 50));
    expect(wrapper.contains('.card-title')).to.be.true;
  });

  it('Displays passed title', async () => {
    const wrapper = mount(ChartCard);
    wrapper.setProps({title: 'test title'});
    await wrapper.vm.$nextTick();
    await new Promise(resolve => setTimeout(resolve, 50));
    expect(wrapper.text()).to.include('test title');
  });
});

可选:提前导入Chartist避免动态加载

如果你不想处理动态import的异步问题,可以直接在测试文件顶部导入Chartist,这样组件里的import('chartist')会直接使用已加载的模块:

import Chartist from 'chartist';
// 可选:如果不想让Chartist实际渲染图表,可以用Sinon等工具stub它的方法
import sinon from 'sinon';
sinon.stub(Chartist, 'Line');
sinon.stub(Chartist, 'Pie');
sinon.stub(Chartist, 'Bar');

这样修改后,你的测试不仅能通过,还不会再出现那个Cannot create property 'uncaught' on string的错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:27:11