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

如何用JestMock file-saver的saveAs测试DevExtreme导出功能

解决Jest中Mock file-saver saveAs方法的报错问题

问题场景

在为DevExtreme DataGrid的CSV下载方法编写单元测试时,调用以下代码环节出现mock异常:

saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.csv')

报错信息

(0 , _fileSaver.default) is not a function

业务代码与测试代码

下载函数

const downloadCsv = () => {
  const workbook = new Workbook()
  const worksheet = workbook.addWorksheet('Main Sheet')
  const exportRes = exportDataGrid({
    component: state.gridInstance,
    worksheet: worksheet
  })
  exportRes.then(() => {
    workbook.csv.writeBuffer().then((buffer) => {
      saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.csv')
    })
  })
}

Jest测试文件

import { shallowMount } from '@vue/test-utils'
import downloadComp from '@/components/data-grid/downloadComp'

jest.mock('devextreme/excel_exporter', () => ({
  exportDataGrid: jest.fn(
    () => new Promise((r) => r({ data: { from: { row: 1, column: 1 }, to: { row: 26, column: 8 } } }))
  )
}))

jest.mock('exceljs', () => {
  return {
    Workbook: jest.fn().mockImplementation(() => {
      return {
        addWorksheet: () => {},
        csv: {
          workbook: {},
          worksheet: null,
          writeBuffer: jest.fn(
            () => new Promise((r) => r({ data: { from: { row: 1, column: 1 }, to: { row: 26, column: 8 } } }))
          )
        }
      }
    })
  }
})

jest.mock('file-saver', () => ({ saveAs: jest.fn() }))
describe('Download grid', () => {
  let wrapper

  beforeEach(() => {
    wrapper = shallowMount(downloadComp)
  })

  it('method handleDownload', () => {
    wrapper.vm.downloadCsv()
  })
})

解决方案

核心问题

file-saver默认采用默认导出而非命名导出,当前mock写法按命名导出处理,导致找不到对应方法。

修正Mock写法

将file-saver的mock改为模拟默认导出:

jest.mock('file-saver', () => ({
  default: jest.fn()
}))

匹配导入方式

确保业务代码中使用默认导入:

import saveAs from 'file-saver'

如果业务代码用的是命名导入(import { saveAs } from 'file-saver'),需兼容两种导出方式,修改mock如下:

jest.mock('file-saver', () => {
  const saveAsMock = jest.fn()
  return {
    default: saveAsMock,
    saveAs: saveAsMock
  }
})

处理异步测试逻辑

由于下载函数包含多层Promise,测试时需等待异步操作完成后再断言:

it('method handleDownload', async () => {
  await wrapper.vm.downloadCsv()
  const saveAs = require('file-saver').default
  expect(saveAs).toHaveBeenCalled()
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:45:46