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

如何在单个文件中用Vitest测试含try/catch的public-ip mock逻辑?

当然可行!

完全可以把成功和异常场景的测试合并到同一个文件里,用Vitest的describe块对不同测试场景分组,既能保证逻辑清晰,也方便维护。

具体实现思路

  1. 用vi.mock()全局mockpublic-ip库,在不同测试场景中动态修改它的返回值或抛出异常
  2. 用describe分别包裹「成功获取IP」和「异常处理」的测试用例,明确区分不同逻辑分支
  3. 异常场景下要额外验证日志是否被正确记录

示例代码

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { getPublicIp } from './your-file-path'
import publicIp from 'public-ip'

// 全局mock public-ip库
vi.mock('public-ip', () => ({
  default: vi.fn()
}))

// 假设用console.error记录错误日志,自定义logger同理
const mockConsoleError = vi.spyOn(console, 'error').mockImplementation(() => {})

describe('getPublicIp 函数测试', () => {
  beforeEach(() => {
    // 每个测试前重置mock状态,避免用例间污染
    vi.clearAllMocks()
  })

  describe('成功场景', () => {
    it('返回正确的公网IP', async () => {
      // 模拟public-ip成功返回IP
      publicIp.default.mockResolvedValue('114.114.114.114')
      
      const result = await getPublicIp()
      expect(result).toBe('114.114.114.114')
      expect(publicIp.default).toHaveBeenCalledTimes(1)
    })
  })

  describe('异常场景', () => {
    it('记录错误日志并返回空字符串', async () => {
      // 模拟public-ip抛出异常
      const mockError = new Error('请求超时')
      publicIp.default.mockRejectedValue(mockError)
      
      const result = await getPublicIp()
      expect(result).toBe('')
      expect(publicIp.default).toHaveBeenCalledTimes(1)
      expect(mockConsoleError).toHaveBeenCalledWith('获取公网IP出错:', mockError)
    })
  })
})

注意事项

  • 用beforeEach重置mock的调用状态,防止不同测试用例互相干扰
  • 如果使用自定义日志工具,需要同样mock并验证其调用情况
  • 分组后的测试用例会在Vitest报告中按层级展示,可读性更强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 09:32:08