使用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
相关产品推荐
相关产品推荐

