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

Vue3使用Jest测试文件上传时遇undefined错误的解决方法

解决Jest测试Quasar文件上传组件时的expect(received).toEqual(expected)异常

问题描述

我尝试用Jest为文件上传和Excel导出功能编写单元测试,在测试文件上传逻辑时遇到了深度相等断言失败的异常,预期值为{},实际值为undefined。

组件代码(Vue + Quasar)

<template>
  <div class="q-gutter-y-xs row items-start">
    <q-card flat style="width: 100%" dense>      
      <Page-Content
        ref="pageContent"
      >
        <template #header>
          <div class="q-px-md">
            <div class="q-gutter-sm row">
              <q-item class="col-4 col-sm-12" style="margin-left: 0">                
                <q-file
                  name="selectuploadfile"
                  standout="bg-blue-1 text-indigo"
                  outlined
                  dense
                  style="width: 270px"
                  v-model="ExcelList"
                  :label="$t('select_upload_file')"
                >
                  <template v-slot:prepend>
                    <q-icon name="cloud_upload" @click.stop />
                  </template>
                  <template v-slot:append>
                    <q-icon
                      name="close"
                      @click.stop="ExcelList = null"
                      class="cursor-pointer"
                    />
                  </template>
                </q-file>
                <q-btn
                  :label="$t('upload')"
                  @click="importExcel"
                />
                <q-btn    
                  :label="$t('upload_sample')"
                  href="./UploadSample/AverageYearsDataDefine.xlsx"
                />
                <q-btn
                  :label="$t('export_to_excel')"
                  @click="exportExcel"
                />
              </q-item>
            </div>
          </div>
        </template>
      </Page-Content>
    </q-card>
  </div>
</template>

测试代码

describe('AverageYearsDataDefine', () => {
  it('fill up form', async () => {    

    const file = new File(['test file'], 'test.xlsx', {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    });
    const fileInput = wrapper.get('[name="selectuploadfile"]');
    await fileInput.trigger('change', file);
    expect(wrapper.vm.ExcelList).toEqual(file);
  });
});

错误信息

expect(received).toEqual(expected) // deep equality
预期值:{}
实际值:undefined

解决方案

1. 定位Quasar q-file内部的原生input元素

Quasar的q-file是封装后的组件,直接触发组件本身的change事件无效,必须找到其内部的原生<input type="file">元素:

// 方法1:通过组件名称查找
const qFileComponent = wrapper.findComponent({ name: 'QFile' });
const nativeInput = qFileComponent.find('input[type="file"]');

// 方法2:通过属性查找内部input
const nativeInput = wrapper.find('[name="selectuploadfile"] input[type="file"]');

2. 构造符合规范的FileList对象

原生文件输入框的change事件中,target.files是FileList类型,而非单个File对象,需要手动构造:

const file = new File(['test file'], 'test.xlsx', {
  type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
// 构造FileList
const fileList = Object.assign(new FileList(), { 0: file, length: 1 });

3. 正确触发事件并等待组件更新

触发原生input的change事件时,需要传递包含files属性的事件对象,并等待Vue完成响应式更新:

await nativeInput.trigger('change', {
  target: { files: fileList }
});
// 等待组件更新
await wrapper.vm.$nextTick();

4. 确保组件数据正确声明

确认组件的ExcelList是在data中声明的响应式数据:

export default {
  data() {
    return {
      ExcelList: null
    };
  },
  // ...其他方法
};

修改后的测试代码

describe('AverageYearsDataDefine', () => {
  it('fill up form', async () => {    
    const file = new File(['test file'], 'test.xlsx', {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    });
    const fileList = Object.assign(new FileList(), { 0: file, length: 1 });
    
    // 找到原生input
    const qFileComponent = wrapper.findComponent({ name: 'QFile' });
    const nativeInput = qFileComponent.find('input[type="file"]');
    
    // 触发事件并等待更新
    await nativeInput.trigger('change', { target: { files: fileList } });
    await wrapper.vm.$nextTick();
    
    expect(wrapper.vm.ExcelList).toEqual(file);
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 01:12:29