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

Vitest报错:mock模块未定义formatWeatherData导出求助

解决Vitest Mock模块时"formatWeatherData导出未定义"的错误

问题场景

我有一个格式化天气API数据的函数formatWeatherData,想通过MockgetWeatherData接口调用生成固定测试数据,单独验证格式化逻辑。但运行Vitest测试时抛出错误:

Error: [vitest] No "formatWeatherData" export is defined on the "../controller/weatherApiController.ts" mock. Did you forget to return it from "vi.mock"?

相关代码如下:

weatherApiController.ts(注意:原代码存在循环导入问题,需删除开头无效的import)

// 删掉此行循环导入:import { getWeatherData, formatWeatherData} from '../controller/weatherApiController'
import { describe, expect, vi, test } from 'vitest'

export async function formatWeatherData(start: String, end: String){
    let data = await getWeatherData(start, end)
    let formattedTemps = []
    for(let i = 0; i < data.days.length; i++){
        formattedTemps.push({datetime: data.days[i]['datetime'], tempmax: data.days[i]['tempmax'], tempmin: data.days[i]['tempmin']})
    }
    return formattedTemps
}

export async function getWeatherData(start: String, end: String) {
    try{
        let response = await fetch(`https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/Wermelskirchen/${start}/${end}?unitGroup=metric&include=days%2Ccurrent&key=<apiKey>&contentType=json`);
        if(!response.ok){
            throw new Error(`HTTP Error! Status: ${response.status}`);
        }
        let data = await response.json()
        return data
    }catch(error){
        console.error(error)
        return null
    }
}

原测试代码(存在问题)

test('mock3', async()=> {
    let expected = [
  { datetime: '2023-03-12', tempmax: 10.4, tempmin: -0.2 },
  { datetime: '2023-03-13', tempmax: 15.4, tempmin: 9.1 }
]
    vi.mock('../controller/weatherApiController.ts', async() => {
        const actual = await vi.importActual("../controller/weatherApiController.ts")
        return {
          actual,
          getWeatherData: async() => {
            number: 3
          },
          formatWeatherData: async() => {
            number:4
          }
        }
      });
      const result = await formatWeatherData('2023-03-12', '2023-03-13')
      expect(result).toEqual(expected)
})

错误原因

  1. 模块导出结构错误:在vi.mock返回对象中,你将actual作为一个属性返回,而非展开其导出内容,导致原模块的formatWeatherData未被正确暴露。
  2. 不必要的Mock目标:formatWeatherData是你要测试的核心函数,不需要Mock它,应该保留原实现,仅Mock依赖的getWeatherData。
  3. Mock返回值格式不符:当前getWeatherData的Mock返回{number:3},完全不符合formatWeatherData所需的包含days数组的结构,会导致后续循环逻辑报错。

修复方案

按以下规则修改测试代码:

  • 用对象展开运算符...actual导入原模块的所有导出,确保formatWeatherData能正常访问
  • 仅替换getWeatherData的实现,返回符合API格式的模拟数据
  • 移除对formatWeatherData的Mock,保留原函数逻辑用于测试

完整修复后的测试代码

import { describe, expect, vi, test } from 'vitest'
import { formatWeatherData } from '../controller/weatherApiController'

// vi.mock需放在模块顶部/测试外部,确保模块加载时生效
vi.mock('../controller/weatherApiController.ts', async () => {
  const actual = await vi.importActual('../controller/weatherApiController.ts')
  return {
    ...actual, // 展开原模块所有导出,保留formatWeatherData原实现
    getWeatherData: async () => {
      // 返回与真实API结构一致的模拟数据
      return {
        days: [
          { datetime: '2023-03-12', tempmax: 10.4, tempmin: -0.2 },
          { datetime: '2023-03-13', tempmax: 15.4, tempmin: 9.1 }
        ]
      }
    }
  }
})

test('测试formatWeatherData格式化逻辑', async () => {
  const expected = [
    { datetime: '2023-03-12', tempmax: 10.4, tempmin: -0.2 },
    { datetime: '2023-03-13', tempmax: 15.4, tempmin: 9.1 }
  ]
  
  const result = await formatWeatherData('2023-03-12', '2023-03-13')
  expect(result).toEqual(expected)
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:13:17