如何在单个文件中用Vitest测试含try/catch的public-ip mock逻辑?
当然可行!
完全可以把成功和异常场景的测试合并到同一个文件里,用Vitest的describe块对不同测试场景分组,既能保证逻辑清晰,也方便维护。
具体实现思路
- 用
vi.mock()全局mockpublic-ip库,在不同测试场景中动态修改它的返回值或抛出异常 - 用
describe分别包裹「成功获取IP」和「异常处理」的测试用例,明确区分不同逻辑分支 - 异常场景下要额外验证日志是否被正确记录
示例代码
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
相关产品推荐
相关产品推荐

